diff options
Diffstat (limited to 'src')
256 files changed, 42275 insertions, 2906 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 7811b0ae..33894dc1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -24,7 +24,17 @@ AM_LDFLAGS = $(PTHREAD_CFLAGS) # If I say "dist_include_DATA", automake complains that $(includedir) is not # a "legitimate" directory for DATA. Screw you, automake. protodir = $(includedir) -nobase_dist_proto_DATA = google/protobuf/descriptor.proto \ +nobase_dist_proto_DATA = google/protobuf/descriptor.proto \ + google/protobuf/any.proto \ + google/protobuf/api.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 \ google/protobuf/compiler/plugin.proto # Not sure why these don't get cleaned automatically. @@ -76,13 +86,19 @@ nobase_include_HEADERS = \ google/protobuf/stubs/stl_util.h \ google/protobuf/stubs/template_util.h \ google/protobuf/stubs/type_traits.h \ + google/protobuf/any.pb.h \ + google/protobuf/api.pb.h \ + google/protobuf/any.h \ google/protobuf/arena.h \ google/protobuf/arenastring.h \ google/protobuf/descriptor_database.h \ google/protobuf/descriptor.h \ google/protobuf/descriptor.pb.h \ + google/protobuf/duration.pb.h \ google/protobuf/dynamic_message.h \ + google/protobuf/empty.pb.h \ google/protobuf/extension_set.h \ + google/protobuf/field_mask.pb.h \ google/protobuf/generated_enum_reflection.h \ google/protobuf/generated_enum_util.h \ google/protobuf/generated_message_reflection.h \ @@ -90,8 +106,8 @@ nobase_include_HEADERS = \ google/protobuf/map_entry.h \ google/protobuf/map_entry_lite.h \ google/protobuf/map_field.h \ - google/protobuf/map_field_lite.h \ google/protobuf/map_field_inl.h \ + google/protobuf/map_field_lite.h \ google/protobuf/map.h \ google/protobuf/map_type_handler.h \ google/protobuf/message.h \ @@ -102,11 +118,16 @@ nobase_include_HEADERS = \ google/protobuf/repeated_field.h \ google/protobuf/repeated_field_reflection.h \ google/protobuf/service.h \ + google/protobuf/source_context.pb.h \ + google/protobuf/struct.pb.h \ google/protobuf/text_format.h \ + google/protobuf/timestamp.pb.h \ + google/protobuf/type.pb.h \ google/protobuf/unknown_field_set.h \ google/protobuf/wire_format.h \ google/protobuf/wire_format_lite.h \ google/protobuf/wire_format_lite_inl.h \ + google/protobuf/wrappers.pb.h \ google/protobuf/io/coded_stream.h \ $(GZHEADERS) \ google/protobuf/io/printer.h \ @@ -125,8 +146,11 @@ nobase_include_HEADERS = \ google/protobuf/compiler/java/java_generator.h \ google/protobuf/compiler/java/java_names.h \ google/protobuf/compiler/javanano/javanano_generator.h \ + google/protobuf/compiler/objectivec/objectivec_generator.h \ + google/protobuf/compiler/objectivec/objectivec_helpers.h \ google/protobuf/compiler/python/python_generator.h \ - google/protobuf/compiler/ruby/ruby_generator.h + google/protobuf/compiler/ruby/ruby_generator.h \ + google/protobuf/compiler/csharp/csharp_generator.h nobase_nodist_include_HEADERS = \ $(public_config) @@ -162,25 +186,36 @@ libprotobuf_la_LIBADD = $(PTHREAD_LIBS) libprotobuf_la_LDFLAGS = -version-info 10:0:0 -export-dynamic -no-undefined libprotobuf_la_SOURCES = \ $(libprotobuf_lite_la_SOURCES) \ - google/protobuf/stubs/strutil.cc \ - google/protobuf/stubs/strutil.h \ - google/protobuf/stubs/substitute.cc \ - google/protobuf/stubs/substitute.h \ - google/protobuf/stubs/structurally_valid.cc \ + google/protobuf/any.pb.cc \ + google/protobuf/api.pb.cc \ + google/protobuf/any.cc \ google/protobuf/descriptor.cc \ google/protobuf/descriptor_database.cc \ google/protobuf/descriptor.pb.cc \ + google/protobuf/duration.pb.cc \ google/protobuf/dynamic_message.cc \ + google/protobuf/empty.pb.cc \ google/protobuf/extension_set_heavy.cc \ + google/protobuf/field_mask.pb.cc \ google/protobuf/generated_message_reflection.cc \ google/protobuf/map_field.cc \ google/protobuf/message.cc \ google/protobuf/reflection_internal.h \ google/protobuf/reflection_ops.cc \ google/protobuf/service.cc \ + google/protobuf/source_context.pb.cc \ + google/protobuf/struct.pb.cc \ + google/protobuf/stubs/structurally_valid.cc \ + google/protobuf/stubs/strutil.cc \ + google/protobuf/stubs/strutil.h \ + google/protobuf/stubs/substitute.cc \ + google/protobuf/stubs/substitute.h \ google/protobuf/text_format.cc \ + google/protobuf/timestamp.pb.cc \ + google/protobuf/type.pb.cc \ google/protobuf/unknown_field_set.cc \ google/protobuf/wire_format.cc \ + google/protobuf/wrappers.pb.cc \ google/protobuf/io/gzip_stream.cc \ google/protobuf/io/printer.cc \ google/protobuf/io/strtod.cc \ @@ -232,6 +267,8 @@ libprotoc_la_SOURCES = \ google/protobuf/compiler/java/java_enum.cc \ google/protobuf/compiler/java/java_enum_field.cc \ google/protobuf/compiler/java/java_enum_field.h \ + google/protobuf/compiler/java/java_enum_field_lite.cc \ + google/protobuf/compiler/java/java_enum_field_lite.h \ google/protobuf/compiler/java/java_enum.h \ google/protobuf/compiler/java/java_extension.cc \ google/protobuf/compiler/java/java_extension.h \ @@ -246,22 +283,38 @@ libprotoc_la_SOURCES = \ google/protobuf/compiler/java/java_helpers.h \ google/protobuf/compiler/java/java_lazy_message_field.cc \ google/protobuf/compiler/java/java_lazy_message_field.h \ + google/protobuf/compiler/java/java_lazy_message_field_lite.cc\ + google/protobuf/compiler/java/java_lazy_message_field_lite.h \ google/protobuf/compiler/java/java_map_field.cc \ google/protobuf/compiler/java/java_map_field.h \ + google/protobuf/compiler/java/java_map_field_lite.cc \ + google/protobuf/compiler/java/java_map_field_lite.h \ google/protobuf/compiler/java/java_message.cc \ + google/protobuf/compiler/java/java_message_lite.cc \ + google/protobuf/compiler/java/java_message_builder.cc \ + google/protobuf/compiler/java/java_message_builder_lite.cc \ google/protobuf/compiler/java/java_message_field.cc \ google/protobuf/compiler/java/java_message_field.h \ + google/protobuf/compiler/java/java_message_field_lite.cc \ + google/protobuf/compiler/java/java_message_field_lite.h \ google/protobuf/compiler/java/java_message.h \ + google/protobuf/compiler/java/java_message_lite.h \ + google/protobuf/compiler/java/java_message_builder.h \ + google/protobuf/compiler/java/java_message_builder_lite.h \ google/protobuf/compiler/java/java_name_resolver.cc \ google/protobuf/compiler/java/java_name_resolver.h \ google/protobuf/compiler/java/java_primitive_field.cc \ google/protobuf/compiler/java/java_primitive_field.h \ + google/protobuf/compiler/java/java_primitive_field_lite.cc \ + google/protobuf/compiler/java/java_primitive_field_lite.h \ google/protobuf/compiler/java/java_shared_code_generator.cc \ google/protobuf/compiler/java/java_shared_code_generator.h \ google/protobuf/compiler/java/java_service.cc \ google/protobuf/compiler/java/java_service.h \ google/protobuf/compiler/java/java_string_field.cc \ google/protobuf/compiler/java/java_string_field.h \ + google/protobuf/compiler/java/java_string_field_lite.cc \ + google/protobuf/compiler/java/java_string_field_lite.h \ google/protobuf/compiler/java/java_doc_comment.cc \ google/protobuf/compiler/java/java_doc_comment.h \ google/protobuf/compiler/javanano/javanano_enum.cc \ @@ -287,8 +340,60 @@ libprotoc_la_SOURCES = \ google/protobuf/compiler/javanano/javanano_params.h \ google/protobuf/compiler/javanano/javanano_primitive_field.cc \ google/protobuf/compiler/javanano/javanano_primitive_field.h \ + google/protobuf/compiler/objectivec/objectivec_enum.cc \ + google/protobuf/compiler/objectivec/objectivec_enum.h \ + google/protobuf/compiler/objectivec/objectivec_enum_field.cc \ + google/protobuf/compiler/objectivec/objectivec_enum_field.h \ + google/protobuf/compiler/objectivec/objectivec_extension.cc \ + google/protobuf/compiler/objectivec/objectivec_extension.h \ + google/protobuf/compiler/objectivec/objectivec_field.cc \ + google/protobuf/compiler/objectivec/objectivec_field.h \ + google/protobuf/compiler/objectivec/objectivec_file.cc \ + google/protobuf/compiler/objectivec/objectivec_file.h \ + google/protobuf/compiler/objectivec/objectivec_generator.cc \ + google/protobuf/compiler/objectivec/objectivec_helpers.cc \ + google/protobuf/compiler/objectivec/objectivec_helpers.h \ + google/protobuf/compiler/objectivec/objectivec_map_field.cc \ + google/protobuf/compiler/objectivec/objectivec_map_field.h \ + google/protobuf/compiler/objectivec/objectivec_message.cc \ + google/protobuf/compiler/objectivec/objectivec_message.h \ + google/protobuf/compiler/objectivec/objectivec_message_field.cc \ + google/protobuf/compiler/objectivec/objectivec_message_field.h \ + google/protobuf/compiler/objectivec/objectivec_oneof.cc \ + google/protobuf/compiler/objectivec/objectivec_oneof.h \ + google/protobuf/compiler/objectivec/objectivec_primitive_field.cc \ + google/protobuf/compiler/objectivec/objectivec_primitive_field.h \ google/protobuf/compiler/python/python_generator.cc \ - google/protobuf/compiler/ruby/ruby_generator.cc + google/protobuf/compiler/ruby/ruby_generator.cc \ + google/protobuf/compiler/csharp/csharp_enum.cc \ + google/protobuf/compiler/csharp/csharp_enum.h \ + google/protobuf/compiler/csharp/csharp_enum_field.cc \ + google/protobuf/compiler/csharp/csharp_enum_field.h \ + google/protobuf/compiler/csharp/csharp_extension.cc \ + google/protobuf/compiler/csharp/csharp_extension.h \ + google/protobuf/compiler/csharp/csharp_field_base.cc \ + google/protobuf/compiler/csharp/csharp_field_base.h \ + google/protobuf/compiler/csharp/csharp_generator.cc \ + google/protobuf/compiler/csharp/csharp_helpers.cc \ + google/protobuf/compiler/csharp/csharp_helpers.h \ + google/protobuf/compiler/csharp/csharp_message.cc \ + google/protobuf/compiler/csharp/csharp_message.h \ + google/protobuf/compiler/csharp/csharp_message_field.cc \ + google/protobuf/compiler/csharp/csharp_message_field.h \ + google/protobuf/compiler/csharp/csharp_primitive_field.cc \ + google/protobuf/compiler/csharp/csharp_primitive_field.h \ + google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc \ + google/protobuf/compiler/csharp/csharp_repeated_enum_field.h \ + google/protobuf/compiler/csharp/csharp_repeated_message_field.cc \ + google/protobuf/compiler/csharp/csharp_repeated_message_field.h \ + google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc \ + google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h \ + google/protobuf/compiler/csharp/csharp_source_generator_base.cc \ + google/protobuf/compiler/csharp/csharp_source_generator_base.h \ + google/protobuf/compiler/csharp/csharp_umbrella_class.cc \ + google/protobuf/compiler/csharp/csharp_umbrella_class.h \ + google/protobuf/compiler/csharp/csharp_writer.cc \ + google/protobuf/compiler/csharp/csharp_writer.h bin_PROGRAMS = protoc protoc_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la @@ -297,6 +402,7 @@ protoc_SOURCES = google/protobuf/compiler/main.cc # Tests ============================================================== protoc_inputs = \ + google/protobuf/any_test.proto \ google/protobuf/map_lite_unittest.proto \ google/protobuf/map_proto2_unittest.proto \ google/protobuf/map_unittest.proto \ @@ -321,6 +427,7 @@ protoc_inputs = \ google/protobuf/unittest_preserve_unknown_enum.proto \ google/protobuf/unittest_preserve_unknown_enum2.proto \ google/protobuf/unittest_proto3_arena.proto \ + google/protobuf/unittest_well_known_types.proto \ google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto \ google/protobuf/compiler/cpp/cpp_test_large_enum_value.proto @@ -334,6 +441,7 @@ EXTRA_DIST = \ google/protobuf/testdata/golden_message_proto3 \ google/protobuf/testdata/golden_packed_fields_message \ google/protobuf/testdata/bad_utf8_string \ + google/protobuf/testdata/map_test_data.txt \ google/protobuf/testdata/text_format_unittest_data.txt \ google/protobuf/testdata/text_format_unittest_data_oneof_implemented.txt \ google/protobuf/testdata/text_format_unittest_data_pointy.txt \ @@ -342,6 +450,8 @@ EXTRA_DIST = \ google/protobuf/testdata/text_format_unittest_extensions_data_pointy.txt \ google/protobuf/package_info.h \ google/protobuf/io/package_info.h \ + google/protobuf/compiler/ruby/ruby_generated_code.proto \ + google/protobuf/compiler/ruby/ruby_generated_code.rb \ google/protobuf/compiler/package_info.h \ google/protobuf/compiler/zip_output_unittest.sh \ google/protobuf/unittest_enormous_descriptor.proto @@ -358,6 +468,8 @@ protoc_lite_outputs = \ protoc_outputs = \ $(protoc_lite_outputs) \ + google/protobuf/any_test.pb.cc \ + google/protobuf/any_test.pb.h \ google/protobuf/map_proto2_unittest.pb.cc \ google/protobuf/map_proto2_unittest.pb.h \ google/protobuf/map_unittest.pb.cc \ @@ -398,6 +510,8 @@ protoc_outputs = \ google/protobuf/unittest_preserve_unknown_enum2.pb.h \ google/protobuf/unittest_proto3_arena.pb.cc \ google/protobuf/unittest_proto3_arena.pb.h \ + google/protobuf/unittest_well_known_types.pb.cc \ + google/protobuf/unittest_well_known_types.pb.h \ google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.cc \ google/protobuf/compiler/cpp/cpp_test_large_enum_value.pb.h \ google/protobuf/compiler/cpp/cpp_test_bad_identifiers.pb.cc \ @@ -456,6 +570,7 @@ protobuf_test_SOURCES = \ google/protobuf/stubs/stringprintf_unittest.cc \ google/protobuf/stubs/template_util_unittest.cc \ google/protobuf/stubs/type_traits_unittest.cc \ + google/protobuf/any_test.cc \ google/protobuf/arenastring_unittest.cc \ google/protobuf/arena_unittest.cc \ google/protobuf/descriptor_database_unittest.cc \ @@ -475,6 +590,7 @@ protobuf_test_SOURCES = \ google/protobuf/repeated_field_unittest.cc \ google/protobuf/text_format_unittest.cc \ google/protobuf/unknown_field_set_unittest.cc \ + google/protobuf/well_known_types_unittest.cc \ google/protobuf/wire_format_unittest.cc \ google/protobuf/io/coded_stream_unittest.cc \ google/protobuf/io/printer_unittest.cc \ @@ -491,8 +607,10 @@ protobuf_test_SOURCES = \ google/protobuf/compiler/cpp/cpp_plugin_unittest.cc \ google/protobuf/compiler/java/java_plugin_unittest.cc \ google/protobuf/compiler/java/java_doc_comment_unittest.cc \ + google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc \ google/protobuf/compiler/python/python_plugin_unittest.cc \ google/protobuf/compiler/ruby/ruby_generator_unittest.cc \ + google/protobuf/compiler/csharp/csharp_generator_unittest.cc \ $(COMMON_TEST_SOURCES) nodist_protobuf_test_SOURCES = $(protoc_outputs) @@ -514,6 +632,8 @@ nodist_protobuf_lazy_descriptor_test_SOURCES = $(protoc_outputs) protobuf_lite_test_LDADD = $(PTHREAD_LIBS) libprotobuf-lite.la protobuf_lite_test_CXXFLAGS = $(NO_OPT_CXXFLAGS) protobuf_lite_test_SOURCES = \ + google/protobuf/arena_test_util.cc \ + google/protobuf/arena_test_util.h \ google/protobuf/lite_unittest.cc \ google/protobuf/map_lite_test_util.cc \ google/protobuf/map_lite_test_util.h \ diff --git a/src/google/protobuf/any.cc b/src/google/protobuf/any.cc new file mode 100644 index 00000000..c66fdfad --- /dev/null +++ b/src/google/protobuf/any.cc @@ -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. + +#include <google/protobuf/any.h> + +namespace google { +namespace protobuf { +namespace internal { + +namespace { +string GetTypeUrl(const Descriptor* message) { + return string(kTypeGoogleApisComPrefix) + message->full_name(); +} + +} // namespace + +const char kAnyFullTypeName[] = "google.protobuf.Any"; +const char kTypeGoogleApisComPrefix[] = "type.googleapis.com/"; + +AnyMetadata::AnyMetadata(UrlType* type_url, ValueType* value) + : type_url_(type_url), value_(value) { +} + +void AnyMetadata::PackFrom(const Message& message) { + type_url_->SetNoArena(&::google::protobuf::internal::GetEmptyString(), + GetTypeUrl(message.GetDescriptor())); + message.SerializeToString(value_->MutableNoArena( + &::google::protobuf::internal::GetEmptyStringAlreadyInited())); +} + +bool AnyMetadata::UnpackTo(Message* message) const { + if (!InternalIs(message->GetDescriptor())) { + return false; + } + return message->ParseFromString( + value_->GetNoArena(&::google::protobuf::internal::GetEmptyString())); +} + +bool AnyMetadata::InternalIs(const Descriptor* descriptor) const { + return type_url_->GetNoArena( + &::google::protobuf::internal::GetEmptyString()) == + GetTypeUrl(descriptor); +} + +bool ParseAnyTypeUrl(const string& type_url, string* full_type_name) { + const int prefix_len = strlen(kTypeGoogleApisComPrefix); + if (strncmp(type_url.c_str(), kTypeGoogleApisComPrefix, prefix_len) == 0) { + full_type_name->assign(type_url.data() + prefix_len, + type_url.size() - prefix_len); + return true; + } + return true; +} + + +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 != NULL && + (*type_url_field)->type() == FieldDescriptor::TYPE_STRING && + *value_field != NULL && + (*value_field)->type() == FieldDescriptor::TYPE_BYTES); +} + +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/any.h b/src/google/protobuf/any.h new file mode 100644 index 00000000..f681eceb --- /dev/null +++ b/src/google/protobuf/any.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. + +#ifndef GOOGLE_PROTOBUF_ANY_H__ +#define GOOGLE_PROTOBUF_ANY_H__ + +#include <string> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/message.h> + +namespace google { +namespace protobuf { +namespace internal { + +// Helper class used to implement google::protobuf::Any. +class LIBPROTOBUF_EXPORT AnyMetadata { + typedef ArenaStringPtr UrlType; + typedef ArenaStringPtr ValueType; + public: + // AnyMetadata does not take ownership of "type_url" and "value". + AnyMetadata(UrlType* type_url, ValueType* value); + + void PackFrom(const Message& message); + + bool UnpackTo(Message* message) const; + + template<typename T> + bool Is() const { + return InternalIs(T::default_instance().GetDescriptor()); + } + + private: + bool InternalIs(const Descriptor* message) const; + + UrlType* type_url_; + ValueType* value_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(AnyMetadata); +}; + +extern const char kAnyFullTypeName[]; // "google.protobuf.Any". +extern const char kTypeGoogleApisComPrefix[]; // "type.googleapis.com/". + +// 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 type_url does not start with +// "type.googleapis.com". +bool ParseAnyTypeUrl(const string& type_url, 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 +#endif // GOOGLE_PROTOBUF_ANY_H__ diff --git a/src/google/protobuf/any.pb.cc b/src/google/protobuf/any.pb.cc new file mode 100644 index 00000000..2c492b04 --- /dev/null +++ b/src/google/protobuf/any.pb.cc @@ -0,0 +1,482 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/any.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "google/protobuf/any.pb.h" + +#include <algorithm> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/once.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/wire_format_lite_inl.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/reflection_ops.h> +#include <google/protobuf/wire_format.h> +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { + +namespace { + +const ::google::protobuf::Descriptor* Any_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Any_reflection_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_google_2fprotobuf_2fany_2eproto() { + protobuf_AddDesc_google_2fprotobuf_2fany_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "google/protobuf/any.proto"); + GOOGLE_CHECK(file != NULL); + Any_descriptor_ = file->message_type(0); + static const int Any_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Any, type_url_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Any, value_), + }; + Any_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + Any_descriptor_, + Any::default_instance_, + Any_offsets_, + -1, + -1, + -1, + sizeof(Any), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Any, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Any, _is_default_instance_)); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_google_2fprotobuf_2fany_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Any_descriptor_, &Any::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_google_2fprotobuf_2fany_2eproto() { + delete Any::default_instance_; + delete Any_reflection_; +} + +void protobuf_AddDesc_google_2fprotobuf_2fany_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\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(\014BC\n\023com.google.protobufB\010AnyProtoP\001\240" + "\001\001\242\002\003GPB\252\002\026Google.ProtocolBuffersb\006proto" + "3", 161); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "google/protobuf/any.proto", &protobuf_RegisterTypes); + Any::default_instance_ = new Any(); + Any::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_google_2fprotobuf_2fany_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_google_2fprotobuf_2fany_2eproto { + StaticDescriptorInitializer_google_2fprotobuf_2fany_2eproto() { + protobuf_AddDesc_google_2fprotobuf_2fany_2eproto(); + } +} static_descriptor_initializer_google_2fprotobuf_2fany_2eproto_; + +namespace { + +static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD; +static void MergeFromFail(int line) { + GOOGLE_CHECK(false) << __FILE__ << ":" << line; +} + +} // namespace + + +// =================================================================== + +void Any::PackFrom(const ::google::protobuf::Message& message) { + _any_metadata_.PackFrom(message); +} + +bool Any::UnpackTo(::google::protobuf::Message* message) const { + return _any_metadata_.UnpackTo(message); +} + +#ifndef _MSC_VER +const int Any::kTypeUrlFieldNumber; +const int Any::kValueFieldNumber; +#endif // !_MSC_VER + +Any::Any() + : ::google::protobuf::Message(), _internal_metadata_(NULL), _any_metadata_(&type_url_, &value_) { + SharedCtor(); + // @@protoc_insertion_point(constructor:google.protobuf.Any) +} + +void Any::InitAsDefaultInstance() { + _is_default_instance_ = true; +} + +Any::Any(const Any& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL), + _any_metadata_(&type_url_, &value_) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:google.protobuf.Any) +} + +void Any::SharedCtor() { + _is_default_instance_ = false; + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + type_url_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + +Any::~Any() { + // @@protoc_insertion_point(destructor:google.protobuf.Any) + SharedDtor(); +} + +void Any::SharedDtor() { + type_url_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + value_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (this != default_instance_) { + } +} + +void Any::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Any::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Any_descriptor_; +} + +const Any& Any::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fany_2eproto(); + return *default_instance_; +} + +Any* Any::default_instance_ = NULL; + +Any* Any::New(::google::protobuf::Arena* arena) const { + Any* n = new Any; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void Any::Clear() { + type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + +bool Any::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:google.protobuf.Any) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string type_url = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_type_url())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->type_url().data(), this->type_url().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "google.protobuf.Any.type_url"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_value; + break; + } + + // optional bytes value = 2; + case 2: { + if (tag == 18) { + parse_value: + DO_(::google::protobuf::internal::WireFormatLite::ReadBytes( + input, this->mutable_value())); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:google.protobuf.Any) + return true; +failure: + // @@protoc_insertion_point(parse_failure:google.protobuf.Any) + return false; +#undef DO_ +} + +void Any::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:google.protobuf.Any) + // optional string type_url = 1; + if (this->type_url().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->type_url().data(), this->type_url().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.Any.type_url"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->type_url(), output); + } + + // optional bytes value = 2; + if (this->value().size() > 0) { + ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased( + 2, this->value(), output); + } + + // @@protoc_insertion_point(serialize_end:google.protobuf.Any) +} + +::google::protobuf::uint8* Any::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Any) + // optional string type_url = 1; + if (this->type_url().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->type_url().data(), this->type_url().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.Any.type_url"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->type_url(), target); + } + + // optional bytes value = 2; + if (this->value().size() > 0) { + target = + ::google::protobuf::internal::WireFormatLite::WriteBytesToArray( + 2, this->value(), target); + } + + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Any) + return target; +} + +int Any::ByteSize() const { + int total_size = 0; + + // optional string type_url = 1; + if (this->type_url().size() > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->type_url()); + } + + // optional bytes value = 2; + if (this->value().size() > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::BytesSize( + this->value()); + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Any::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const Any* source = + ::google::protobuf::internal::DynamicCastToGenerated<const Any>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Any::MergeFrom(const Any& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from.type_url().size() > 0) { + + type_url_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.type_url_); + } + if (from.value().size() > 0) { + + value_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.value_); + } +} + +void Any::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Any::CopyFrom(const Any& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Any::IsInitialized() const { + + return true; +} + +void Any::Swap(Any* other) { + if (other == this) return; + InternalSwap(other); +} +void Any::InternalSwap(Any* other) { + type_url_.Swap(&other->type_url_); + value_.Swap(&other->value_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata Any::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Any_descriptor_; + metadata.reflection = Any_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// Any + +// optional string type_url = 1; +void Any::clear_type_url() { + type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + const ::std::string& Any::type_url() const { + // @@protoc_insertion_point(field_get:google.protobuf.Any.type_url) + return type_url_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void Any::set_type_url(const ::std::string& value) { + + type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Any.type_url) +} + void Any::set_type_url(const char* value) { + + type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Any.type_url) +} + void Any::set_type_url(const char* value, size_t size) { + + type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Any.type_url) +} + ::std::string* Any::mutable_type_url() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Any.type_url) + return type_url_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* Any::release_type_url() { + + return type_url_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void Any::set_allocated_type_url(::std::string* type_url) { + if (type_url != NULL) { + + } else { + + } + type_url_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), type_url); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Any.type_url) +} + +// optional bytes value = 2; +void Any::clear_value() { + value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + const ::std::string& Any::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Any.value) + return value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void Any::set_value(const ::std::string& value) { + + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Any.value) +} + void Any::set_value(const char* value) { + + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Any.value) +} + void Any::set_value(const void* value, size_t size) { + + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Any.value) +} + ::std::string* Any::mutable_value() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Any.value) + return value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* Any::release_value() { + + return value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void Any::set_allocated_value(::std::string* value) { + if (value != NULL) { + + } else { + + } + value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Any.value) +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// @@protoc_insertion_point(namespace_scope) + +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) diff --git a/src/google/protobuf/any.pb.h b/src/google/protobuf/any.pb.h new file mode 100644 index 00000000..c324c4af --- /dev/null +++ b/src/google/protobuf/any.pb.h @@ -0,0 +1,250 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/any.proto + +#ifndef PROTOBUF_google_2fprotobuf_2fany_2eproto__INCLUDED +#define PROTOBUF_google_2fprotobuf_2fany_2eproto__INCLUDED + +#include <string> + +#include <google/protobuf/stubs/common.h> + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#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 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include <google/protobuf/arena.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/metadata.h> +#include <google/protobuf/message.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/unknown_field_set.h> +#include "google/protobuf/any.h" +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { + +// Internal implementation detail -- do not call these. +void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fany_2eproto(); +void protobuf_AssignDesc_google_2fprotobuf_2fany_2eproto(); +void protobuf_ShutdownFile_google_2fprotobuf_2fany_2eproto(); + +class Any; + +// =================================================================== + +class LIBPROTOBUF_EXPORT Any : public ::google::protobuf::Message { + public: + Any(); + virtual ~Any(); + + Any(const Any& from); + + inline Any& operator=(const Any& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Any& default_instance(); + + // implements Any ----------------------------------------------- + + void PackFrom(const ::google::protobuf::Message& message); + bool UnpackTo(::google::protobuf::Message* message) const; + template<typename T> bool Is() const { + return _any_metadata_.Is<T>(); + } + + void Swap(Any* other); + + // implements Message ---------------------------------------------- + + inline Any* New() const { return New(NULL); } + + Any* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Any& from); + void MergeFrom(const Any& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Any* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string type_url = 1; + void clear_type_url(); + static const int kTypeUrlFieldNumber = 1; + const ::std::string& type_url() const; + void set_type_url(const ::std::string& value); + void set_type_url(const char* value); + void set_type_url(const char* value, size_t size); + ::std::string* mutable_type_url(); + ::std::string* release_type_url(); + void set_allocated_type_url(::std::string* type_url); + + // optional bytes value = 2; + void clear_value(); + static const int kValueFieldNumber = 2; + const ::std::string& value() const; + void set_value(const ::std::string& value); + void set_value(const char* value); + void set_value(const void* value, size_t size); + ::std::string* mutable_value(); + ::std::string* release_value(); + void set_allocated_value(::std::string* value); + + // @@protoc_insertion_point(class_scope:google.protobuf.Any) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr type_url_; + ::google::protobuf::internal::ArenaStringPtr value_; + mutable int _cached_size_; + ::google::protobuf::internal::AnyMetadata _any_metadata_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fany_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fany_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fany_2eproto(); + + void InitAsDefaultInstance(); + static Any* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// Any + +// optional string type_url = 1; +inline void Any::clear_type_url() { + type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& Any::type_url() const { + // @@protoc_insertion_point(field_get:google.protobuf.Any.type_url) + return type_url_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Any::set_type_url(const ::std::string& value) { + + type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Any.type_url) +} +inline void Any::set_type_url(const char* value) { + + type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Any.type_url) +} +inline void Any::set_type_url(const char* value, size_t size) { + + type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Any.type_url) +} +inline ::std::string* Any::mutable_type_url() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Any.type_url) + return type_url_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* Any::release_type_url() { + + return type_url_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Any::set_allocated_type_url(::std::string* type_url) { + if (type_url != NULL) { + + } else { + + } + type_url_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), type_url); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Any.type_url) +} + +// optional bytes value = 2; +inline void Any::clear_value() { + value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& Any::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Any.value) + return value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Any::set_value(const ::std::string& value) { + + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Any.value) +} +inline void Any::set_value(const char* value) { + + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Any.value) +} +inline void Any::set_value(const void* value, size_t size) { + + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Any.value) +} +inline ::std::string* Any::mutable_value() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Any.value) + return value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* Any::release_value() { + + return value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Any::set_allocated_value(::std::string* value) { + if (value != NULL) { + + } else { + + } + value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Any.value) +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS + +// @@protoc_insertion_point(namespace_scope) + +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_google_2fprotobuf_2fany_2eproto__INCLUDED diff --git a/src/google/protobuf/any.proto b/src/google/protobuf/any.proto index 3aba15b3..e1780fe5 100644 --- a/src/google/protobuf/any.proto +++ b/src/google/protobuf/any.proto @@ -35,6 +35,8 @@ option java_generate_equals_and_hash = true; option java_multiple_files = true; option java_outer_classname = "AnyProto"; option java_package = "com.google.protobuf"; +option csharp_namespace = "Google.ProtocolBuffers"; +option objc_class_prefix = "GPB"; // `Any` contains an arbitrary serialized message along with a URL diff --git a/src/google/protobuf/any_test.cc b/src/google/protobuf/any_test.cc new file mode 100644 index 00000000..1bfaa63d --- /dev/null +++ b/src/google/protobuf/any_test.cc @@ -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. + +#include <google/protobuf/any_test.pb.h> +#include <gtest/gtest.h> + +namespace google { +namespace protobuf { +namespace { + +TEST(AnyTest, TestPackAndUnpack) { + protobuf_unittest::TestAny submessage; + submessage.set_int32_value(12345); + protobuf_unittest::TestAny message; + message.mutable_any_value()->PackFrom(submessage); + + string data = message.SerializeAsString(); + + ASSERT_TRUE(message.ParseFromString(data)); + EXPECT_TRUE(message.has_any_value()); + ASSERT_TRUE(message.any_value().UnpackTo(&submessage)); + EXPECT_EQ(12345, submessage.int32_value()); +} + +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); + + string data = message.SerializeAsString(); + + ASSERT_TRUE(message.ParseFromString(data)); + EXPECT_TRUE(message.has_any_value()); + ASSERT_TRUE(message.any_value().UnpackTo(&any)); + ASSERT_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>()); +} + +} // namespace +} // namespace protobuf + +} // namespace google diff --git a/src/google/protobuf/any_test.proto b/src/google/protobuf/any_test.proto new file mode 100644 index 00000000..0c5b30ba --- /dev/null +++ b/src/google/protobuf/any_test.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. + +syntax = "proto3"; + +package protobuf_unittest; + +import "google/protobuf/any.proto"; + +message TestAny { + int32 int32_value = 1; + google.protobuf.Any any_value = 2; + repeated google.protobuf.Any repeated_any_value = 3; +} diff --git a/src/google/protobuf/api.pb.cc b/src/google/protobuf/api.pb.cc new file mode 100644 index 00000000..434320dc --- /dev/null +++ b/src/google/protobuf/api.pb.cc @@ -0,0 +1,1400 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/api.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "google/protobuf/api.pb.h" + +#include <algorithm> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/once.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/wire_format_lite_inl.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/reflection_ops.h> +#include <google/protobuf/wire_format.h> +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { + +namespace { + +const ::google::protobuf::Descriptor* Api_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Api_reflection_ = NULL; +const ::google::protobuf::Descriptor* Method_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Method_reflection_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto() { + protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "google/protobuf/api.proto"); + GOOGLE_CHECK(file != NULL); + Api_descriptor_ = file->message_type(0); + static const int Api_offsets_[5] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, methods_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, options_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, version_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, source_context_), + }; + Api_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + Api_descriptor_, + Api::default_instance_, + Api_offsets_, + -1, + -1, + -1, + sizeof(Api), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, _is_default_instance_)); + Method_descriptor_ = file->message_type(1); + static const int Method_offsets_[6] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, request_type_url_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, request_streaming_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, response_type_url_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, response_streaming_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, options_), + }; + Method_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + Method_descriptor_, + Method::default_instance_, + Method_offsets_, + -1, + -1, + -1, + sizeof(Method), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, _is_default_instance_)); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Api_descriptor_, &Api::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Method_descriptor_, &Method::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_google_2fprotobuf_2fapi_2eproto() { + delete Api::default_instance_; + delete Api_reflection_; + delete Method::default_instance_; + delete Method_reflection_; +} + +void protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::protobuf_AddDesc_google_2fprotobuf_2fsource_5fcontext_2eproto(); + ::google::protobuf::protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto(); + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\031google/protobuf/api.proto\022\017google.prot" + "obuf\032$google/protobuf/source_context.pro" + "to\032\032google/protobuf/type.proto\"\260\001\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\"\254\001\n\006Method\022\014\n\004name\030\001 \001(\t\022\030\n\020re" + "quest_type_url\030\002 \001(\t\022\031\n\021request_streamin" + "g\030\003 \001(\010\022\031\n\021response_type_url\030\004 \001(\t\022\032\n\022re" + "sponse_streaming\030\005 \001(\010\022(\n\007options\030\006 \003(\0132" + "\027.google.protobuf.OptionB\'\n\023com.google.p" + "rotobufB\010ApiProtoP\001\242\002\003GPBb\006proto3", 513); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "google/protobuf/api.proto", &protobuf_RegisterTypes); + Api::default_instance_ = new Api(); + Method::default_instance_ = new Method(); + Api::default_instance_->InitAsDefaultInstance(); + Method::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_google_2fprotobuf_2fapi_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_google_2fprotobuf_2fapi_2eproto { + StaticDescriptorInitializer_google_2fprotobuf_2fapi_2eproto() { + protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto(); + } +} static_descriptor_initializer_google_2fprotobuf_2fapi_2eproto_; + +namespace { + +static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD; +static void MergeFromFail(int line) { + GOOGLE_CHECK(false) << __FILE__ << ":" << line; +} + +} // namespace + + +// =================================================================== + +#ifndef _MSC_VER +const int Api::kNameFieldNumber; +const int Api::kMethodsFieldNumber; +const int Api::kOptionsFieldNumber; +const int Api::kVersionFieldNumber; +const int Api::kSourceContextFieldNumber; +#endif // !_MSC_VER + +Api::Api() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:google.protobuf.Api) +} + +void Api::InitAsDefaultInstance() { + _is_default_instance_ = true; + source_context_ = const_cast< ::google::protobuf::SourceContext*>(&::google::protobuf::SourceContext::default_instance()); +} + +Api::Api(const Api& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:google.protobuf.Api) +} + +void Api::SharedCtor() { + _is_default_instance_ = false; + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + version_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + source_context_ = NULL; +} + +Api::~Api() { + // @@protoc_insertion_point(destructor:google.protobuf.Api) + SharedDtor(); +} + +void Api::SharedDtor() { + name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + version_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (this != default_instance_) { + delete source_context_; + } +} + +void Api::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Api::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Api_descriptor_; +} + +const Api& Api::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto(); + return *default_instance_; +} + +Api* Api::default_instance_ = NULL; + +Api* Api::New(::google::protobuf::Arena* arena) const { + Api* n = new Api; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void Api::Clear() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + version_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (GetArenaNoVirtual() == NULL && source_context_ != NULL) delete source_context_; + source_context_ = NULL; + methods_.Clear(); + options_.Clear(); +} + +bool Api::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:google.protobuf.Api) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string name = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "google.protobuf.Api.name"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_methods; + break; + } + + // repeated .google.protobuf.Method methods = 2; + case 2: { + if (tag == 18) { + parse_methods: + DO_(input->IncrementRecursionDepth()); + parse_loop_methods: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + input, add_methods())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_loop_methods; + if (input->ExpectTag(26)) goto parse_loop_options; + input->UnsafeDecrementRecursionDepth(); + break; + } + + // repeated .google.protobuf.Option options = 3; + case 3: { + if (tag == 26) { + DO_(input->IncrementRecursionDepth()); + parse_loop_options: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + input, add_options())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(26)) goto parse_loop_options; + input->UnsafeDecrementRecursionDepth(); + if (input->ExpectTag(34)) goto parse_version; + break; + } + + // optional string version = 4; + case 4: { + if (tag == 34) { + parse_version: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_version())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->version().data(), this->version().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "google.protobuf.Api.version"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(42)) goto parse_source_context; + break; + } + + // optional .google.protobuf.SourceContext source_context = 5; + case 5: { + if (tag == 42) { + parse_source_context: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_source_context())); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:google.protobuf.Api) + return true; +failure: + // @@protoc_insertion_point(parse_failure:google.protobuf.Api) + return false; +#undef DO_ +} + +void Api::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:google.protobuf.Api) + // optional string name = 1; + if (this->name().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.Api.name"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->name(), output); + } + + // repeated .google.protobuf.Method methods = 2; + for (unsigned int i = 0, n = this->methods_size(); i < n; i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->methods(i), output); + } + + // repeated .google.protobuf.Option options = 3; + for (unsigned int i = 0, n = this->options_size(); i < n; i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 3, this->options(i), output); + } + + // optional string version = 4; + if (this->version().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->version().data(), this->version().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.Api.version"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 4, this->version(), output); + } + + // optional .google.protobuf.SourceContext source_context = 5; + if (this->has_source_context()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 5, *this->source_context_, output); + } + + // @@protoc_insertion_point(serialize_end:google.protobuf.Api) +} + +::google::protobuf::uint8* Api::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Api) + // optional string name = 1; + if (this->name().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.Api.name"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); + } + + // repeated .google.protobuf.Method methods = 2; + for (unsigned int i = 0, n = this->methods_size(); i < n; i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->methods(i), target); + } + + // repeated .google.protobuf.Option options = 3; + for (unsigned int i = 0, n = this->options_size(); i < n; i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 3, this->options(i), target); + } + + // optional string version = 4; + if (this->version().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->version().data(), this->version().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.Api.version"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 4, this->version(), target); + } + + // optional .google.protobuf.SourceContext source_context = 5; + if (this->has_source_context()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 5, *this->source_context_, target); + } + + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Api) + return target; +} + +int Api::ByteSize() const { + int total_size = 0; + + // optional string name = 1; + if (this->name().size() > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + // optional string version = 4; + if (this->version().size() > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->version()); + } + + // optional .google.protobuf.SourceContext source_context = 5; + if (this->has_source_context()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + *this->source_context_); + } + + // repeated .google.protobuf.Method methods = 2; + total_size += 1 * this->methods_size(); + for (int i = 0; i < this->methods_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->methods(i)); + } + + // repeated .google.protobuf.Option options = 3; + total_size += 1 * this->options_size(); + for (int i = 0; i < this->options_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->options(i)); + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Api::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const Api* source = + ::google::protobuf::internal::DynamicCastToGenerated<const Api>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Api::MergeFrom(const Api& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + methods_.MergeFrom(from.methods_); + options_.MergeFrom(from.options_); + if (from.name().size() > 0) { + + name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); + } + if (from.version().size() > 0) { + + version_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.version_); + } + if (from.has_source_context()) { + mutable_source_context()->::google::protobuf::SourceContext::MergeFrom(from.source_context()); + } +} + +void Api::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Api::CopyFrom(const Api& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Api::IsInitialized() const { + + return true; +} + +void Api::Swap(Api* other) { + if (other == this) return; + InternalSwap(other); +} +void Api::InternalSwap(Api* other) { + name_.Swap(&other->name_); + methods_.UnsafeArenaSwap(&other->methods_); + options_.UnsafeArenaSwap(&other->options_); + version_.Swap(&other->version_); + std::swap(source_context_, other->source_context_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata Api::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Api_descriptor_; + metadata.reflection = Api_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// Api + +// optional string name = 1; +void Api::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + const ::std::string& Api::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.Api.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void Api::set_name(const ::std::string& value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Api.name) +} + void Api::set_name(const char* value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Api.name) +} + void Api::set_name(const char* value, size_t size) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Api.name) +} + ::std::string* Api::mutable_name() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Api.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* Api::release_name() { + + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void Api::set_allocated_name(::std::string* name) { + if (name != NULL) { + + } else { + + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Api.name) +} + +// repeated .google.protobuf.Method methods = 2; +int Api::methods_size() const { + return methods_.size(); +} +void Api::clear_methods() { + methods_.Clear(); +} + const ::google::protobuf::Method& Api::methods(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Api.methods) + return methods_.Get(index); +} + ::google::protobuf::Method* Api::mutable_methods(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Api.methods) + return methods_.Mutable(index); +} + ::google::protobuf::Method* Api::add_methods() { + // @@protoc_insertion_point(field_add:google.protobuf.Api.methods) + return methods_.Add(); +} + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Method >& +Api::methods() const { + // @@protoc_insertion_point(field_list:google.protobuf.Api.methods) + return methods_; +} + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Method >* +Api::mutable_methods() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.methods) + return &methods_; +} + +// repeated .google.protobuf.Option options = 3; +int Api::options_size() const { + return options_.size(); +} +void Api::clear_options() { + options_.Clear(); +} + const ::google::protobuf::Option& Api::options(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Api.options) + return options_.Get(index); +} + ::google::protobuf::Option* Api::mutable_options(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Api.options) + return options_.Mutable(index); +} + ::google::protobuf::Option* Api::add_options() { + // @@protoc_insertion_point(field_add:google.protobuf.Api.options) + return options_.Add(); +} + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >& +Api::options() const { + // @@protoc_insertion_point(field_list:google.protobuf.Api.options) + return options_; +} + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >* +Api::mutable_options() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.options) + return &options_; +} + +// optional string version = 4; +void Api::clear_version() { + version_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + const ::std::string& Api::version() const { + // @@protoc_insertion_point(field_get:google.protobuf.Api.version) + return version_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void Api::set_version(const ::std::string& value) { + + version_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Api.version) +} + void Api::set_version(const char* value) { + + version_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Api.version) +} + void Api::set_version(const char* value, size_t size) { + + version_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Api.version) +} + ::std::string* Api::mutable_version() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Api.version) + return version_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* Api::release_version() { + + return version_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void Api::set_allocated_version(::std::string* version) { + if (version != NULL) { + + } else { + + } + version_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), version); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Api.version) +} + +// optional .google.protobuf.SourceContext source_context = 5; +bool Api::has_source_context() const { + return !_is_default_instance_ && source_context_ != NULL; +} +void Api::clear_source_context() { + if (GetArenaNoVirtual() == NULL && source_context_ != NULL) delete source_context_; + source_context_ = NULL; +} + const ::google::protobuf::SourceContext& Api::source_context() const { + // @@protoc_insertion_point(field_get:google.protobuf.Api.source_context) + return source_context_ != NULL ? *source_context_ : *default_instance_->source_context_; +} + ::google::protobuf::SourceContext* Api::mutable_source_context() { + + if (source_context_ == NULL) { + source_context_ = new ::google::protobuf::SourceContext; + } + // @@protoc_insertion_point(field_mutable:google.protobuf.Api.source_context) + return source_context_; +} + ::google::protobuf::SourceContext* Api::release_source_context() { + + ::google::protobuf::SourceContext* temp = source_context_; + source_context_ = NULL; + return temp; +} + void Api::set_allocated_source_context(::google::protobuf::SourceContext* source_context) { + delete source_context_; + source_context_ = source_context; + if (source_context) { + + } else { + + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Api.source_context) +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// =================================================================== + +#ifndef _MSC_VER +const int Method::kNameFieldNumber; +const int Method::kRequestTypeUrlFieldNumber; +const int Method::kRequestStreamingFieldNumber; +const int Method::kResponseTypeUrlFieldNumber; +const int Method::kResponseStreamingFieldNumber; +const int Method::kOptionsFieldNumber; +#endif // !_MSC_VER + +Method::Method() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:google.protobuf.Method) +} + +void Method::InitAsDefaultInstance() { + _is_default_instance_ = true; +} + +Method::Method(const Method& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:google.protobuf.Method) +} + +void Method::SharedCtor() { + _is_default_instance_ = false; + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + request_type_url_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + request_streaming_ = false; + response_type_url_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + response_streaming_ = false; +} + +Method::~Method() { + // @@protoc_insertion_point(destructor:google.protobuf.Method) + SharedDtor(); +} + +void Method::SharedDtor() { + name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + request_type_url_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + response_type_url_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (this != default_instance_) { + } +} + +void Method::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Method::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Method_descriptor_; +} + +const Method& Method::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto(); + return *default_instance_; +} + +Method* Method::default_instance_ = NULL; + +Method* Method::New(::google::protobuf::Arena* arena) const { + Method* n = new Method; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void Method::Clear() { +#define ZR_HELPER_(f) reinterpret_cast<char*>(\ + &reinterpret_cast<Method*>(16)->f) + +#define ZR_(first, last) do {\ + ::memset(&first, 0,\ + ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\ +} while (0) + + ZR_(request_streaming_, response_streaming_); + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + request_type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + response_type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + +#undef ZR_HELPER_ +#undef ZR_ + + options_.Clear(); +} + +bool Method::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:google.protobuf.Method) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string name = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "google.protobuf.Method.name"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_request_type_url; + break; + } + + // optional string request_type_url = 2; + case 2: { + if (tag == 18) { + parse_request_type_url: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_request_type_url())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->request_type_url().data(), this->request_type_url().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "google.protobuf.Method.request_type_url"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_request_streaming; + break; + } + + // optional bool request_streaming = 3; + case 3: { + if (tag == 24) { + parse_request_streaming: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &request_streaming_))); + + } else { + goto handle_unusual; + } + if (input->ExpectTag(34)) goto parse_response_type_url; + break; + } + + // optional string response_type_url = 4; + case 4: { + if (tag == 34) { + parse_response_type_url: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_response_type_url())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->response_type_url().data(), this->response_type_url().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "google.protobuf.Method.response_type_url"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(40)) goto parse_response_streaming; + break; + } + + // optional bool response_streaming = 5; + case 5: { + if (tag == 40) { + parse_response_streaming: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &response_streaming_))); + + } else { + goto handle_unusual; + } + if (input->ExpectTag(50)) goto parse_options; + break; + } + + // repeated .google.protobuf.Option options = 6; + case 6: { + if (tag == 50) { + parse_options: + DO_(input->IncrementRecursionDepth()); + parse_loop_options: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + input, add_options())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(50)) goto parse_loop_options; + input->UnsafeDecrementRecursionDepth(); + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:google.protobuf.Method) + return true; +failure: + // @@protoc_insertion_point(parse_failure:google.protobuf.Method) + return false; +#undef DO_ +} + +void Method::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:google.protobuf.Method) + // optional string name = 1; + if (this->name().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.Method.name"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->name(), output); + } + + // optional string request_type_url = 2; + if (this->request_type_url().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->request_type_url().data(), this->request_type_url().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.Method.request_type_url"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 2, this->request_type_url(), output); + } + + // optional bool request_streaming = 3; + if (this->request_streaming() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->request_streaming(), output); + } + + // optional string response_type_url = 4; + if (this->response_type_url().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->response_type_url().data(), this->response_type_url().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.Method.response_type_url"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 4, this->response_type_url(), output); + } + + // optional bool response_streaming = 5; + if (this->response_streaming() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteBool(5, this->response_streaming(), output); + } + + // repeated .google.protobuf.Option options = 6; + for (unsigned int i = 0, n = this->options_size(); i < n; i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 6, this->options(i), output); + } + + // @@protoc_insertion_point(serialize_end:google.protobuf.Method) +} + +::google::protobuf::uint8* Method::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Method) + // optional string name = 1; + if (this->name().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.Method.name"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); + } + + // optional string request_type_url = 2; + if (this->request_type_url().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->request_type_url().data(), this->request_type_url().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.Method.request_type_url"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 2, this->request_type_url(), target); + } + + // optional bool request_streaming = 3; + if (this->request_streaming() != 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->request_streaming(), target); + } + + // optional string response_type_url = 4; + if (this->response_type_url().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->response_type_url().data(), this->response_type_url().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.Method.response_type_url"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 4, this->response_type_url(), target); + } + + // optional bool response_streaming = 5; + if (this->response_streaming() != 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(5, this->response_streaming(), target); + } + + // repeated .google.protobuf.Option options = 6; + for (unsigned int i = 0, n = this->options_size(); i < n; i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 6, this->options(i), target); + } + + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Method) + return target; +} + +int Method::ByteSize() const { + int total_size = 0; + + // optional string name = 1; + if (this->name().size() > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + // optional string request_type_url = 2; + if (this->request_type_url().size() > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->request_type_url()); + } + + // optional bool request_streaming = 3; + if (this->request_streaming() != 0) { + total_size += 1 + 1; + } + + // optional string response_type_url = 4; + if (this->response_type_url().size() > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->response_type_url()); + } + + // optional bool response_streaming = 5; + if (this->response_streaming() != 0) { + total_size += 1 + 1; + } + + // repeated .google.protobuf.Option options = 6; + total_size += 1 * this->options_size(); + for (int i = 0; i < this->options_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->options(i)); + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Method::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const Method* source = + ::google::protobuf::internal::DynamicCastToGenerated<const Method>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Method::MergeFrom(const Method& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + options_.MergeFrom(from.options_); + if (from.name().size() > 0) { + + name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); + } + if (from.request_type_url().size() > 0) { + + request_type_url_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.request_type_url_); + } + if (from.request_streaming() != 0) { + set_request_streaming(from.request_streaming()); + } + if (from.response_type_url().size() > 0) { + + response_type_url_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.response_type_url_); + } + if (from.response_streaming() != 0) { + set_response_streaming(from.response_streaming()); + } +} + +void Method::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Method::CopyFrom(const Method& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Method::IsInitialized() const { + + return true; +} + +void Method::Swap(Method* other) { + if (other == this) return; + InternalSwap(other); +} +void Method::InternalSwap(Method* other) { + name_.Swap(&other->name_); + request_type_url_.Swap(&other->request_type_url_); + std::swap(request_streaming_, other->request_streaming_); + response_type_url_.Swap(&other->response_type_url_); + std::swap(response_streaming_, other->response_streaming_); + options_.UnsafeArenaSwap(&other->options_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata Method::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Method_descriptor_; + metadata.reflection = Method_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// Method + +// optional string name = 1; +void Method::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + const ::std::string& Method::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.Method.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void Method::set_name(const ::std::string& value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Method.name) +} + void Method::set_name(const char* value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Method.name) +} + void Method::set_name(const char* value, size_t size) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Method.name) +} + ::std::string* Method::mutable_name() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Method.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* Method::release_name() { + + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void Method::set_allocated_name(::std::string* name) { + if (name != NULL) { + + } else { + + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.name) +} + +// optional string request_type_url = 2; +void Method::clear_request_type_url() { + request_type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + const ::std::string& Method::request_type_url() const { + // @@protoc_insertion_point(field_get:google.protobuf.Method.request_type_url) + return request_type_url_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void Method::set_request_type_url(const ::std::string& value) { + + request_type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Method.request_type_url) +} + void Method::set_request_type_url(const char* value) { + + request_type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Method.request_type_url) +} + void Method::set_request_type_url(const char* value, size_t size) { + + request_type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Method.request_type_url) +} + ::std::string* Method::mutable_request_type_url() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Method.request_type_url) + return request_type_url_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* Method::release_request_type_url() { + + return request_type_url_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void Method::set_allocated_request_type_url(::std::string* request_type_url) { + if (request_type_url != NULL) { + + } else { + + } + request_type_url_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), request_type_url); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.request_type_url) +} + +// optional bool request_streaming = 3; +void Method::clear_request_streaming() { + request_streaming_ = false; +} + bool Method::request_streaming() const { + // @@protoc_insertion_point(field_get:google.protobuf.Method.request_streaming) + return request_streaming_; +} + void Method::set_request_streaming(bool value) { + + request_streaming_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Method.request_streaming) +} + +// optional string response_type_url = 4; +void Method::clear_response_type_url() { + response_type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + const ::std::string& Method::response_type_url() const { + // @@protoc_insertion_point(field_get:google.protobuf.Method.response_type_url) + return response_type_url_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void Method::set_response_type_url(const ::std::string& value) { + + response_type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Method.response_type_url) +} + void Method::set_response_type_url(const char* value) { + + response_type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Method.response_type_url) +} + void Method::set_response_type_url(const char* value, size_t size) { + + response_type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Method.response_type_url) +} + ::std::string* Method::mutable_response_type_url() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Method.response_type_url) + return response_type_url_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* Method::release_response_type_url() { + + return response_type_url_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void Method::set_allocated_response_type_url(::std::string* response_type_url) { + if (response_type_url != NULL) { + + } else { + + } + response_type_url_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), response_type_url); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.response_type_url) +} + +// optional bool response_streaming = 5; +void Method::clear_response_streaming() { + response_streaming_ = false; +} + bool Method::response_streaming() const { + // @@protoc_insertion_point(field_get:google.protobuf.Method.response_streaming) + return response_streaming_; +} + void Method::set_response_streaming(bool value) { + + response_streaming_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Method.response_streaming) +} + +// repeated .google.protobuf.Option options = 6; +int Method::options_size() const { + return options_.size(); +} +void Method::clear_options() { + options_.Clear(); +} + const ::google::protobuf::Option& Method::options(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Method.options) + return options_.Get(index); +} + ::google::protobuf::Option* Method::mutable_options(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Method.options) + return options_.Mutable(index); +} + ::google::protobuf::Option* Method::add_options() { + // @@protoc_insertion_point(field_add:google.protobuf.Method.options) + return options_.Add(); +} + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >& +Method::options() const { + // @@protoc_insertion_point(field_list:google.protobuf.Method.options) + return options_; +} + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >* +Method::mutable_options() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Method.options) + return &options_; +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// @@protoc_insertion_point(namespace_scope) + +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) diff --git a/src/google/protobuf/api.pb.h b/src/google/protobuf/api.pb.h new file mode 100644 index 00000000..985adc5d --- /dev/null +++ b/src/google/protobuf/api.pb.h @@ -0,0 +1,703 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/api.proto + +#ifndef PROTOBUF_google_2fprotobuf_2fapi_2eproto__INCLUDED +#define PROTOBUF_google_2fprotobuf_2fapi_2eproto__INCLUDED + +#include <string> + +#include <google/protobuf/stubs/common.h> + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#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 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include <google/protobuf/arena.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/metadata.h> +#include <google/protobuf/message.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/unknown_field_set.h> +#include "google/protobuf/source_context.pb.h" +#include "google/protobuf/type.pb.h" +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { + +// Internal implementation detail -- do not call these. +void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto(); +void protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto(); +void protobuf_ShutdownFile_google_2fprotobuf_2fapi_2eproto(); + +class Api; +class Method; + +// =================================================================== + +class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message { + public: + Api(); + virtual ~Api(); + + Api(const Api& from); + + inline Api& operator=(const Api& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Api& default_instance(); + + void Swap(Api* other); + + // implements Message ---------------------------------------------- + + inline Api* New() const { return New(NULL); } + + Api* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Api& from); + void MergeFrom(const Api& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Api* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string name = 1; + void clear_name(); + static const int kNameFieldNumber = 1; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // repeated .google.protobuf.Method methods = 2; + int methods_size() const; + void clear_methods(); + static const int kMethodsFieldNumber = 2; + const ::google::protobuf::Method& methods(int index) const; + ::google::protobuf::Method* mutable_methods(int index); + ::google::protobuf::Method* add_methods(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Method >& + methods() const; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Method >* + mutable_methods(); + + // repeated .google.protobuf.Option options = 3; + int options_size() const; + void clear_options(); + static const int kOptionsFieldNumber = 3; + const ::google::protobuf::Option& options(int index) const; + ::google::protobuf::Option* mutable_options(int index); + ::google::protobuf::Option* add_options(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >& + options() const; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >* + mutable_options(); + + // optional string version = 4; + void clear_version(); + static const int kVersionFieldNumber = 4; + const ::std::string& version() const; + void set_version(const ::std::string& value); + void set_version(const char* value); + void set_version(const char* value, size_t size); + ::std::string* mutable_version(); + ::std::string* release_version(); + void set_allocated_version(::std::string* version); + + // optional .google.protobuf.SourceContext source_context = 5; + bool has_source_context() const; + void clear_source_context(); + static const int kSourceContextFieldNumber = 5; + const ::google::protobuf::SourceContext& source_context() const; + ::google::protobuf::SourceContext* mutable_source_context(); + ::google::protobuf::SourceContext* release_source_context(); + void set_allocated_source_context(::google::protobuf::SourceContext* source_context); + + // @@protoc_insertion_point(class_scope:google.protobuf.Api) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Method > methods_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_; + ::google::protobuf::internal::ArenaStringPtr version_; + ::google::protobuf::SourceContext* source_context_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fapi_2eproto(); + + void InitAsDefaultInstance(); + static Api* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message { + public: + Method(); + virtual ~Method(); + + Method(const Method& from); + + inline Method& operator=(const Method& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Method& default_instance(); + + void Swap(Method* other); + + // implements Message ---------------------------------------------- + + inline Method* New() const { return New(NULL); } + + Method* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Method& from); + void MergeFrom(const Method& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Method* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string name = 1; + void clear_name(); + static const int kNameFieldNumber = 1; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // optional string request_type_url = 2; + void clear_request_type_url(); + static const int kRequestTypeUrlFieldNumber = 2; + const ::std::string& request_type_url() const; + void set_request_type_url(const ::std::string& value); + void set_request_type_url(const char* value); + void set_request_type_url(const char* value, size_t size); + ::std::string* mutable_request_type_url(); + ::std::string* release_request_type_url(); + void set_allocated_request_type_url(::std::string* request_type_url); + + // optional bool request_streaming = 3; + void clear_request_streaming(); + static const int kRequestStreamingFieldNumber = 3; + bool request_streaming() const; + void set_request_streaming(bool value); + + // optional string response_type_url = 4; + void clear_response_type_url(); + static const int kResponseTypeUrlFieldNumber = 4; + const ::std::string& response_type_url() const; + void set_response_type_url(const ::std::string& value); + void set_response_type_url(const char* value); + void set_response_type_url(const char* value, size_t size); + ::std::string* mutable_response_type_url(); + ::std::string* release_response_type_url(); + void set_allocated_response_type_url(::std::string* response_type_url); + + // optional bool response_streaming = 5; + void clear_response_streaming(); + static const int kResponseStreamingFieldNumber = 5; + bool response_streaming() const; + void set_response_streaming(bool value); + + // repeated .google.protobuf.Option options = 6; + int options_size() const; + void clear_options(); + static const int kOptionsFieldNumber = 6; + const ::google::protobuf::Option& options(int index) const; + ::google::protobuf::Option* mutable_options(int index); + ::google::protobuf::Option* add_options(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >& + options() const; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >* + mutable_options(); + + // @@protoc_insertion_point(class_scope:google.protobuf.Method) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::internal::ArenaStringPtr request_type_url_; + ::google::protobuf::internal::ArenaStringPtr response_type_url_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_; + bool request_streaming_; + bool response_streaming_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fapi_2eproto(); + + void InitAsDefaultInstance(); + static Method* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// Api + +// optional string name = 1; +inline void Api::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& Api::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.Api.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Api::set_name(const ::std::string& value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Api.name) +} +inline void Api::set_name(const char* value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Api.name) +} +inline void Api::set_name(const char* value, size_t size) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Api.name) +} +inline ::std::string* Api::mutable_name() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Api.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* Api::release_name() { + + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Api::set_allocated_name(::std::string* name) { + if (name != NULL) { + + } else { + + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Api.name) +} + +// repeated .google.protobuf.Method methods = 2; +inline int Api::methods_size() const { + return methods_.size(); +} +inline void Api::clear_methods() { + methods_.Clear(); +} +inline const ::google::protobuf::Method& Api::methods(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Api.methods) + return methods_.Get(index); +} +inline ::google::protobuf::Method* Api::mutable_methods(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Api.methods) + return methods_.Mutable(index); +} +inline ::google::protobuf::Method* Api::add_methods() { + // @@protoc_insertion_point(field_add:google.protobuf.Api.methods) + return methods_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Method >& +Api::methods() const { + // @@protoc_insertion_point(field_list:google.protobuf.Api.methods) + return methods_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::Method >* +Api::mutable_methods() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.methods) + return &methods_; +} + +// repeated .google.protobuf.Option options = 3; +inline int Api::options_size() const { + return options_.size(); +} +inline void Api::clear_options() { + options_.Clear(); +} +inline const ::google::protobuf::Option& Api::options(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Api.options) + return options_.Get(index); +} +inline ::google::protobuf::Option* Api::mutable_options(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Api.options) + return options_.Mutable(index); +} +inline ::google::protobuf::Option* Api::add_options() { + // @@protoc_insertion_point(field_add:google.protobuf.Api.options) + return options_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >& +Api::options() const { + // @@protoc_insertion_point(field_list:google.protobuf.Api.options) + return options_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >* +Api::mutable_options() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.options) + return &options_; +} + +// optional string version = 4; +inline void Api::clear_version() { + version_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& Api::version() const { + // @@protoc_insertion_point(field_get:google.protobuf.Api.version) + return version_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Api::set_version(const ::std::string& value) { + + version_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Api.version) +} +inline void Api::set_version(const char* value) { + + version_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Api.version) +} +inline void Api::set_version(const char* value, size_t size) { + + version_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Api.version) +} +inline ::std::string* Api::mutable_version() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Api.version) + return version_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* Api::release_version() { + + return version_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Api::set_allocated_version(::std::string* version) { + if (version != NULL) { + + } else { + + } + version_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), version); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Api.version) +} + +// optional .google.protobuf.SourceContext source_context = 5; +inline bool Api::has_source_context() const { + return !_is_default_instance_ && source_context_ != NULL; +} +inline void Api::clear_source_context() { + if (GetArenaNoVirtual() == NULL && source_context_ != NULL) delete source_context_; + source_context_ = NULL; +} +inline const ::google::protobuf::SourceContext& Api::source_context() const { + // @@protoc_insertion_point(field_get:google.protobuf.Api.source_context) + return source_context_ != NULL ? *source_context_ : *default_instance_->source_context_; +} +inline ::google::protobuf::SourceContext* Api::mutable_source_context() { + + if (source_context_ == NULL) { + source_context_ = new ::google::protobuf::SourceContext; + } + // @@protoc_insertion_point(field_mutable:google.protobuf.Api.source_context) + return source_context_; +} +inline ::google::protobuf::SourceContext* Api::release_source_context() { + + ::google::protobuf::SourceContext* temp = source_context_; + source_context_ = NULL; + return temp; +} +inline void Api::set_allocated_source_context(::google::protobuf::SourceContext* source_context) { + delete source_context_; + source_context_ = source_context; + if (source_context) { + + } else { + + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Api.source_context) +} + +// ------------------------------------------------------------------- + +// Method + +// optional string name = 1; +inline void Method::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& Method::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.Method.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Method::set_name(const ::std::string& value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Method.name) +} +inline void Method::set_name(const char* value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Method.name) +} +inline void Method::set_name(const char* value, size_t size) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Method.name) +} +inline ::std::string* Method::mutable_name() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Method.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* Method::release_name() { + + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Method::set_allocated_name(::std::string* name) { + if (name != NULL) { + + } else { + + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.name) +} + +// optional string request_type_url = 2; +inline void Method::clear_request_type_url() { + request_type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& Method::request_type_url() const { + // @@protoc_insertion_point(field_get:google.protobuf.Method.request_type_url) + return request_type_url_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Method::set_request_type_url(const ::std::string& value) { + + request_type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Method.request_type_url) +} +inline void Method::set_request_type_url(const char* value) { + + request_type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Method.request_type_url) +} +inline void Method::set_request_type_url(const char* value, size_t size) { + + request_type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Method.request_type_url) +} +inline ::std::string* Method::mutable_request_type_url() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Method.request_type_url) + return request_type_url_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* Method::release_request_type_url() { + + return request_type_url_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Method::set_allocated_request_type_url(::std::string* request_type_url) { + if (request_type_url != NULL) { + + } else { + + } + request_type_url_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), request_type_url); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.request_type_url) +} + +// optional bool request_streaming = 3; +inline void Method::clear_request_streaming() { + request_streaming_ = false; +} +inline bool Method::request_streaming() const { + // @@protoc_insertion_point(field_get:google.protobuf.Method.request_streaming) + return request_streaming_; +} +inline void Method::set_request_streaming(bool value) { + + request_streaming_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Method.request_streaming) +} + +// optional string response_type_url = 4; +inline void Method::clear_response_type_url() { + response_type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& Method::response_type_url() const { + // @@protoc_insertion_point(field_get:google.protobuf.Method.response_type_url) + return response_type_url_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Method::set_response_type_url(const ::std::string& value) { + + response_type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Method.response_type_url) +} +inline void Method::set_response_type_url(const char* value) { + + response_type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Method.response_type_url) +} +inline void Method::set_response_type_url(const char* value, size_t size) { + + response_type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Method.response_type_url) +} +inline ::std::string* Method::mutable_response_type_url() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Method.response_type_url) + return response_type_url_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* Method::release_response_type_url() { + + return response_type_url_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Method::set_allocated_response_type_url(::std::string* response_type_url) { + if (response_type_url != NULL) { + + } else { + + } + response_type_url_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), response_type_url); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Method.response_type_url) +} + +// optional bool response_streaming = 5; +inline void Method::clear_response_streaming() { + response_streaming_ = false; +} +inline bool Method::response_streaming() const { + // @@protoc_insertion_point(field_get:google.protobuf.Method.response_streaming) + return response_streaming_; +} +inline void Method::set_response_streaming(bool value) { + + response_streaming_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Method.response_streaming) +} + +// repeated .google.protobuf.Option options = 6; +inline int Method::options_size() const { + return options_.size(); +} +inline void Method::clear_options() { + options_.Clear(); +} +inline const ::google::protobuf::Option& Method::options(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Method.options) + return options_.Get(index); +} +inline ::google::protobuf::Option* Method::mutable_options(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Method.options) + return options_.Mutable(index); +} +inline ::google::protobuf::Option* Method::add_options() { + // @@protoc_insertion_point(field_add:google.protobuf.Method.options) + return options_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >& +Method::options() const { + // @@protoc_insertion_point(field_list:google.protobuf.Method.options) + return options_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >* +Method::mutable_options() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Method.options) + return &options_; +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS +// ------------------------------------------------------------------- + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_google_2fprotobuf_2fapi_2eproto__INCLUDED diff --git a/src/google/protobuf/api.proto b/src/google/protobuf/api.proto index 00857f55..f368c24d 100644 --- a/src/google/protobuf/api.proto +++ b/src/google/protobuf/api.proto @@ -37,6 +37,7 @@ import "google/protobuf/type.proto"; option java_multiple_files = true; option java_outer_classname = "ApiProto"; option java_package = "com.google.protobuf"; +option objc_class_prefix = "GPB"; // Api is a light-weight descriptor for a protocol buffer service. diff --git a/src/google/protobuf/arena.cc b/src/google/protobuf/arena.cc index bda37413..96009645 100755 --- a/src/google/protobuf/arena.cc +++ b/src/google/protobuf/arena.cc @@ -43,6 +43,12 @@ Arena::ThreadCache& Arena::thread_cache() { static GOOGLE_THREAD_LOCAL ThreadCache thread_cache_ = { -1, NULL }; return thread_cache_; } +#elif defined(GOOGLE_PROTOBUF_OS_ANDROID) || defined(GOOGLE_PROTOBUF_OS_IPHONE) +Arena::ThreadCache& Arena::thread_cache() { + static internal::ThreadLocalStorage<ThreadCache>* thread_cache_ = + new internal::ThreadLocalStorage<ThreadCache>(); + return *thread_cache_->Get(); +} #else GOOGLE_THREAD_LOCAL Arena::ThreadCache Arena::thread_cache_ = { -1, NULL }; #endif @@ -148,10 +154,16 @@ void Arena::AddListNode(void* elem, void (*cleanup)(void*)) { reinterpret_cast<google::protobuf::internal::AtomicWord>(node))); } -void* Arena::AllocateAligned(size_t n) { +void* Arena::AllocateAligned(const std::type_info* allocated, size_t n) { // Align n to next multiple of 8 (from Hacker's Delight, Chapter 3.) n = (n + 7) & -8; + // Monitor allocation if needed. + if (GOOGLE_PREDICT_FALSE(hooks_cookie_ != NULL) && + options_.on_arena_allocation != NULL) { + options_.on_arena_allocation(allocated, n, hooks_cookie_); + } + // 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. diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h index bb15e80c..6c3f606e 100644 --- a/src/google/protobuf/arena.h +++ b/src/google/protobuf/arena.h @@ -28,12 +28,12 @@ // (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 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_ARENA_H__ #define GOOGLE_PROTOBUF_ARENA_H__ +#if __cplusplus >= 201103L +#include <google/protobuf/stubs/type_traits.h> +#endif #include <typeinfo> #include <google/protobuf/stubs/atomic_sequence_num.h> @@ -113,10 +113,13 @@ struct ArenaOptions { void (*on_arena_reset)(Arena* arena, void* cookie, uint64 space_used); void (*on_arena_destruction)(Arena* arena, void* cookie, uint64 space_used); - // type_name is promised to be a static string - its lifetime extends to - // match program's lifetime. - void (*on_arena_allocation)(const char* type_name, uint64 alloc_size, - Arena* arena, void* cookie); + // 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) + void (*on_arena_allocation)(const std::type_info* allocated_type, + uint64 alloc_size, void* cookie); ArenaOptions() : start_block_size(kDefaultStartBlockSize), @@ -137,6 +140,14 @@ struct ArenaOptions { static const size_t kDefaultMaxBlockSize = 8192; }; +// Support for non-RTTI environments. (The metrics hooks API uses type +// information.) +#ifndef GOOGLE_PROTOBUF_NO_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 @@ -146,6 +157,44 @@ struct ArenaOptions { // 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>, is as +// follows: +// +// - The type T must have (at least) two constructors: a constructor with no +// arguments, called when a T is allocated on the heap; and a constructor with +// a google::protobuf::Arena* argument, 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 (no-argument) 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. +// +// - One- and two-user-argument forms of CreateMessage<T>() also exist that +// forward these constructor arguments to T's constructor: for example, +// CreateMessage<T>(Arena*, arg1, arg2) forwards to a constructor T(Arena*, +// arg1, arg2). +// +// This protocol is implemented by all arena-enabled proto2 message classes as +// well as RepeatedPtrField. class LIBPROTOBUF_EXPORT Arena { public: // Arena constructor taking custom options. See ArenaOptions below for @@ -172,8 +221,10 @@ class LIBPROTOBUF_EXPORT Arena { // compilation error will occur. // // RepeatedField and RepeatedPtrField may also be instantiated directly on an - // arena with this method: they act as "arena-capable message types" for the - // purposes of the Arena API. + // arena with this method. + // + // This function also accepts any type T that satisfies the arena message + // allocation protocol, documented above. template <typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE static T* CreateMessage(::google::protobuf::Arena* arena) { if (arena == NULL) { @@ -183,17 +234,55 @@ class LIBPROTOBUF_EXPORT Arena { } } + // One-argument form of CreateMessage. This is useful for constructing objects + // that implement the arena message construction protocol described above but + // take additional constructor arguments. + template <typename T, typename Arg> GOOGLE_ATTRIBUTE_ALWAYS_INLINE + static T* CreateMessage(::google::protobuf::Arena* arena, const Arg& arg) { + if (arena == NULL) { + return new T(NULL, arg); + } else { + return arena->CreateMessageInternal<T>(static_cast<T*>(0), + arg); + } + } + + // Two-argument form of CreateMessage. This is useful for constructing objects + // that implement the arena message construction protocol described above but + // take additional constructor arguments. + template <typename T, typename Arg1, typename Arg2> GOOGLE_ATTRIBUTE_ALWAYS_INLINE + static T* CreateMessage(::google::protobuf::Arena* arena, + const Arg1& arg1, + const Arg2& arg2) { + if (arena == NULL) { + return new T(NULL, arg1, arg2); + } else { + return arena->CreateMessageInternal<T>(static_cast<T*>(0), + arg1, arg2); + } + } + // 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> GOOGLE_ATTRIBUTE_ALWAYS_INLINE static T* Create(::google::protobuf::Arena* arena) { if (arena == NULL) { return new T(); } else { - return arena->CreateInternal<T>( - SkipDeleteList<T>(static_cast<T*>(0))); + return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value); } } @@ -203,7 +292,7 @@ class LIBPROTOBUF_EXPORT Arena { if (arena == NULL) { return new T(arg); } else { - return arena->CreateInternal<T>(SkipDeleteList<T>(static_cast<T*>(0)), + return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value, arg); } } @@ -214,9 +303,8 @@ class LIBPROTOBUF_EXPORT Arena { if (arena == NULL) { return new T(arg1, arg2); } else { - return arena->CreateInternal<T>(SkipDeleteList<T>(static_cast<T*>(0)), - arg1, - arg2); + return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value, + arg1, arg2); } } @@ -229,10 +317,8 @@ class LIBPROTOBUF_EXPORT Arena { if (arena == NULL) { return new T(arg1, arg2, arg3); } else { - return arena->CreateInternal<T>(SkipDeleteList<T>(static_cast<T*>(0)), - arg1, - arg2, - arg3); + return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value, + arg1, arg2, arg3); } } @@ -246,20 +332,89 @@ class LIBPROTOBUF_EXPORT Arena { if (arena == NULL) { return new T(arg1, arg2, arg3, arg4); } else { - return arena->CreateInternal<T>(SkipDeleteList<T>(static_cast<T*>(0)), - arg1, - arg2, - arg3, - arg4); + return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value, + arg1, arg2, arg3, arg4); } } - // Create an array of object type T on the arena. Type T must have a trivial - // constructor, as it will not be invoked when created on the arena. + // Version of the above with five constructor arguments for the created + // object. + template <typename T, typename Arg1, typename Arg2, typename Arg3, + typename Arg4, typename Arg5> + GOOGLE_ATTRIBUTE_ALWAYS_INLINE static T* Create(::google::protobuf::Arena* arena, + const Arg1& arg1, const Arg2& arg2, + const Arg3& arg3, const Arg4& arg4, + const Arg5& arg5) { + if (arena == NULL) { + return new T(arg1, arg2, arg3, arg4, arg5); + } else { + return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value, + arg1, arg2, arg3, arg4, arg5); + } + } + + // Version of the above with six constructor arguments for the created + // object. + template <typename T, typename Arg1, typename Arg2, typename Arg3, + typename Arg4, typename Arg5, typename Arg6> + GOOGLE_ATTRIBUTE_ALWAYS_INLINE static T* Create(::google::protobuf::Arena* arena, + const Arg1& arg1, const Arg2& arg2, + const Arg3& arg3, const Arg4& arg4, + const Arg5& arg5, const Arg6& arg6) { + if (arena == NULL) { + return new T(arg1, arg2, arg3, arg4, arg5, arg6); + } else { + return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value, + arg1, arg2, arg3, arg4, arg5, arg6); + } + } + + // Version of the above with seven constructor arguments for the created + // object. + template <typename T, typename Arg1, typename Arg2, typename Arg3, + typename Arg4, typename Arg5, typename Arg6, typename Arg7> + GOOGLE_ATTRIBUTE_ALWAYS_INLINE static T* Create(::google::protobuf::Arena* arena, + const Arg1& arg1, const Arg2& arg2, + const Arg3& arg3, const Arg4& arg4, + const Arg5& arg5, const Arg6& arg6, + const Arg7& arg7) { + if (arena == NULL) { + return new T(arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } else { + return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value, + arg1, arg2, arg3, arg4, arg5, arg6, arg7); + } + } + + // Version of the above with eight constructor arguments for the created + // object. + template <typename T, typename Arg1, typename Arg2, typename Arg3, + typename Arg4, typename Arg5, typename Arg6, typename Arg7, + typename Arg8> + GOOGLE_ATTRIBUTE_ALWAYS_INLINE static T* Create(::google::protobuf::Arena* arena, + const Arg1& arg1, const Arg2& arg2, + const Arg3& arg3, const Arg4& arg4, + const Arg5& arg5, const Arg6& arg6, + const Arg7& arg7, const Arg8& arg8) { + if (arena == NULL) { + return new T(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } else { + return arena->CreateInternal<T>( + google::protobuf::internal::has_trivial_destructor<T>::value, + arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + } + } + + // 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> GOOGLE_ATTRIBUTE_ALWAYS_INLINE static T* CreateArray(::google::protobuf::Arena* arena, size_t num_elements) { if (arena == NULL) { - return new T[num_elements]; + return static_cast<T*>(::operator new[](num_elements * sizeof(T))); } else { return arena->CreateInternalRawArray<T>(num_elements); } @@ -373,23 +528,27 @@ class LIBPROTOBUF_EXPORT Arena { // Thread local variables cannot be exposed through DLL interface but we can // wrap them in static functions. static ThreadCache& thread_cache(); +#elif defined(GOOGLE_PROTOBUF_OS_ANDROID) || defined(GOOGLE_PROTOBUF_OS_IPHONE) + // Android ndk does not support GOOGLE_THREAD_LOCAL keyword so we use a custom thread + // local storage class we implemented. + // iOS also does not support the GOOGLE_THREAD_LOCAL keyword. + static ThreadCache& thread_cache(); #else static GOOGLE_THREAD_LOCAL ThreadCache thread_cache_; static ThreadCache& thread_cache() { return thread_cache_; } #endif - // SFINAE for skipping addition to delete list for a Type. This is mainly to - // skip proto2/proto1 message objects with cc_enable_arenas=true from being - // part of the delete list. Also, note, compiler will optimize out the branch - // in CreateInternal<T>. - // + // SFINAE for skipping addition to delete list for a message type when created + // with CreateMessage. This is mainly to skip proto2/proto1 message objects + // with cc_enable_arenas=true from being part of the delete list. Also, note, + // compiler will optimize out the branch in CreateInternal<T>. template<typename T> static inline bool SkipDeleteList(typename T::DestructorSkippable_*) { return true; } - // For non message objects, we skip addition to delete list if the object has - // a trivial destructor. + // For message objects that don't have the DestructorSkippable_ trait, we + // always add to the delete list. template<typename T> static inline bool SkipDeleteList(...) { return google::protobuf::internal::has_trivial_destructor<T>::value; @@ -414,14 +573,15 @@ class LIBPROTOBUF_EXPORT Arena { // Just allocate the required size for the given type assuming the // type has a trivial constructor. template<typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE - inline T* CreateInternalRawArray(uint32 num_elements) { - return static_cast<T*>(AllocateAligned(sizeof(T) * num_elements)); + inline T* CreateInternalRawArray(size_t num_elements) { + return static_cast<T*>( + AllocateAligned(RTTI_TYPE_ID(T), sizeof(T) * num_elements)); } template <typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE inline T* CreateInternal( bool skip_explicit_ownership) { - T* t = new (AllocateAligned(sizeof(T))) T(); + T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) T(); if (!skip_explicit_ownership) { AddListNode(t, &internal::arena_destruct_object<T>); } @@ -431,7 +591,7 @@ class LIBPROTOBUF_EXPORT Arena { template <typename T, typename Arg> GOOGLE_ATTRIBUTE_ALWAYS_INLINE inline T* CreateInternal( bool skip_explicit_ownership, const Arg& arg) { - T* t = new (AllocateAligned(sizeof(T))) T(arg); + T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) T(arg); if (!skip_explicit_ownership) { AddListNode(t, &internal::arena_destruct_object<T>); } @@ -441,7 +601,7 @@ class LIBPROTOBUF_EXPORT Arena { template <typename T, typename Arg1, typename Arg2> GOOGLE_ATTRIBUTE_ALWAYS_INLINE inline T* CreateInternal( bool skip_explicit_ownership, const Arg1& arg1, const Arg2& arg2) { - T* t = new (AllocateAligned(sizeof(T))) T(arg1, arg2); + T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) T(arg1, arg2); if (!skip_explicit_ownership) { AddListNode(t, &internal::arena_destruct_object<T>); } @@ -453,7 +613,8 @@ class LIBPROTOBUF_EXPORT Arena { const Arg1& arg1, const Arg2& arg2, const Arg3& arg3) { - T* t = new (AllocateAligned(sizeof(T))) T(arg1, arg2, arg3); + T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) + T(arg1, arg2, arg3); if (!skip_explicit_ownership) { AddListNode(t, &internal::arena_destruct_object<T>); } @@ -467,7 +628,79 @@ class LIBPROTOBUF_EXPORT Arena { const Arg2& arg2, const Arg3& arg3, const Arg4& arg4) { - T* t = new (AllocateAligned(sizeof(T))) T(arg1, arg2, arg3, arg4); + T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) + T(arg1, arg2, arg3, arg4); + if (!skip_explicit_ownership) { + AddListNode(t, &internal::arena_destruct_object<T>); + } + return t; + } + + template <typename T, typename Arg1, typename Arg2, typename Arg3, + typename Arg4, typename Arg5> + GOOGLE_ATTRIBUTE_ALWAYS_INLINE inline T* CreateInternal(bool skip_explicit_ownership, + const Arg1& arg1, + const Arg2& arg2, + const Arg3& arg3, + const Arg4& arg4, + const Arg5& arg5) { + T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) + T(arg1, arg2, arg3, arg4, arg5); + if (!skip_explicit_ownership) { + AddListNode(t, &internal::arena_destruct_object<T>); + } + return t; + } + + template <typename T, typename Arg1, typename Arg2, typename Arg3, + typename Arg4, typename Arg5, typename Arg6> + GOOGLE_ATTRIBUTE_ALWAYS_INLINE inline T* CreateInternal(bool skip_explicit_ownership, + const Arg1& arg1, + const Arg2& arg2, + const Arg3& arg3, + const Arg4& arg4, + const Arg5& arg5, + const Arg6& arg6) { + T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) + T(arg1, arg2, arg3, arg4, arg5, arg6); + if (!skip_explicit_ownership) { + AddListNode(t, &internal::arena_destruct_object<T>); + } + return t; + } + + template <typename T, typename Arg1, typename Arg2, typename Arg3, + typename Arg4, typename Arg5, typename Arg6, typename Arg7> + GOOGLE_ATTRIBUTE_ALWAYS_INLINE inline T* CreateInternal(bool skip_explicit_ownership, + const Arg1& arg1, + const Arg2& arg2, + const Arg3& arg3, + const Arg4& arg4, + const Arg5& arg5, + const Arg6& arg6, + const Arg7& arg7) { + T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) + T(arg1, arg2, arg3, arg4, arg5, arg6, arg7); + if (!skip_explicit_ownership) { + AddListNode(t, &internal::arena_destruct_object<T>); + } + return t; + } + + template <typename T, typename Arg1, typename Arg2, typename Arg3, + typename Arg4, typename Arg5, typename Arg6, typename Arg7, + typename Arg8> + GOOGLE_ATTRIBUTE_ALWAYS_INLINE inline T* CreateInternal(bool skip_explicit_ownership, + const Arg1& arg1, + const Arg2& arg2, + const Arg3& arg3, + const Arg4& arg4, + const Arg5& arg5, + const Arg6& arg6, + const Arg7& arg7, + const Arg8& arg8) { + T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) + T(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); if (!skip_explicit_ownership) { AddListNode(t, &internal::arena_destruct_object<T>); } @@ -480,6 +713,20 @@ class LIBPROTOBUF_EXPORT Arena { this); } + template <typename T, typename Arg> GOOGLE_ATTRIBUTE_ALWAYS_INLINE + inline T* CreateMessageInternal(typename T::InternalArenaConstructable_*, + const Arg& arg) { + return CreateInternal<T, Arena*>(SkipDeleteList<T>(static_cast<T*>(0)), + this, arg); + } + + template <typename T, typename Arg1, typename Arg2> GOOGLE_ATTRIBUTE_ALWAYS_INLINE + inline T* CreateMessageInternal(typename T::InternalArenaConstructable_*, + const Arg1& arg1, const Arg2& arg2) { + return CreateInternal<T, Arena*>(SkipDeleteList<T>(static_cast<T*>(0)), + this, arg1, arg2); + } + // CreateInArenaStorage is used to implement map field. Without it, // google::protobuf::Map need to call generated message's protected arena constructor, // which needs to declare google::protobuf::Map as friend of generated message. @@ -531,8 +778,15 @@ class LIBPROTOBUF_EXPORT Arena { return NULL; } + // Allocate and also optionally call on_arena_allocation callback with the + // allocated type info when the hooks are in place in ArenaOptions and + // the cookie is not null. + void* AllocateAligned(const std::type_info* allocated, size_t n); - void* AllocateAligned(size_t size); + // Allocate an internal allocation, avoiding optional typed monitoring. + GOOGLE_ATTRIBUTE_ALWAYS_INLINE inline void* AllocateAligned(size_t n) { + return AllocateAligned(NULL, n); + } void Init(); @@ -591,6 +845,9 @@ class LIBPROTOBUF_EXPORT Arena { GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Arena); }; +// Defined above for supporting environments without RTTI. +#undef RTTI_TYPE_ID + template<typename T> const typename Arena::is_arena_constructable<T>::type Arena::is_arena_constructable<T>::value = diff --git a/src/google/protobuf/arena_nc_test.py b/src/google/protobuf/arena_nc_test.py index fc510a48..87a69b2a 100644 --- a/src/google/protobuf/arena_nc_test.py +++ b/src/google/protobuf/arena_nc_test.py @@ -1,4 +1,4 @@ -#! /usr/bin/python +#! /usr/bin/env python # # Protocol Buffers - Google's data interchange format # Copyright 2008 Google Inc. All rights reserved. @@ -35,6 +35,7 @@ import unittest from google3.testing.pybase import fake_target_util +import unittest class ArenaNcTest(unittest.TestCase): diff --git a/src/google/protobuf/arena_test_util.h b/src/google/protobuf/arena_test_util.h index 7db7a90e..690cc706 100644 --- a/src/google/protobuf/arena_test_util.h +++ b/src/google/protobuf/arena_test_util.h @@ -31,6 +31,7 @@ #ifndef GOOGLE_PROTOBUF_ARENA_TEST_UTIL_H__ #define GOOGLE_PROTOBUF_ARENA_TEST_UTIL_H__ + namespace google { namespace protobuf { namespace internal { diff --git a/src/google/protobuf/arena_unittest.cc b/src/google/protobuf/arena_unittest.cc index d9b198e0..6c185695 100644 --- a/src/google/protobuf/arena_unittest.cc +++ b/src/google/protobuf/arena_unittest.cc @@ -30,8 +30,6 @@ #include <google/protobuf/arena.h> -#include <stdint.h> - #include <algorithm> #include <cstring> #include <memory> @@ -39,6 +37,7 @@ #include <google/protobuf/stubs/shared_ptr.h> #endif #include <string> +#include <typeinfo> #include <vector> #include <google/protobuf/stubs/common.h> @@ -47,11 +46,14 @@ #include <google/protobuf/unittest.pb.h> #include <google/protobuf/unittest_arena.pb.h> #include <google/protobuf/unittest_no_arena.pb.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl_lite.h> #include <google/protobuf/descriptor.h> #include <google/protobuf/extension_set.h> #include <google/protobuf/message.h> #include <google/protobuf/message_lite.h> #include <google/protobuf/repeated_field.h> +#include <google/protobuf/wire_format_lite.h> #include <google/protobuf/unknown_field_set.h> #include <gtest/gtest.h> @@ -125,6 +127,29 @@ class MustBeConstructedWithOneThroughFour { 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 string& three, + const PleaseDontCopyMe* four, int five, const char* six, + const string& seven, const string& eight) + : one_(one), two_(two), three_(three), four_(four), five_(five), + six_(six), seven_(seven), eight_(eight) {} + + int one_; + const char* const two_; + string three_; + const PleaseDontCopyMe* four_; + int five_; + const char* const six_; + string seven_; + string eight_; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MustBeConstructedWithOneThroughEight); +}; + } // namespace TEST(ArenaTest, ArenaConstructable) { @@ -156,7 +181,7 @@ TEST(ArenaTest, BasicCreate) { EXPECT_EQ(2, notifier.GetCount()); } -TEST(ArenaTest, CreateWithManyConstructorArguments) { +TEST(ArenaTest, CreateWithFourConstructorArguments) { Arena arena; const string three("3"); const PleaseDontCopyMe four(4); @@ -170,6 +195,26 @@ TEST(ArenaTest, CreateWithManyConstructorArguments) { ASSERT_EQ(4, new_object->four_->value()); } +TEST(ArenaTest, CreateWithEightConstructorArguments) { + Arena arena; + const string three("3"); + const PleaseDontCopyMe four(4); + const string seven("7"); + const 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_); +} + TEST(ArenaTest, InitialBlockTooSmall) { // Construct a small (64 byte) initial block of memory to be used by the // arena allocator; then, allocate an object which will not fit in the @@ -1113,6 +1158,19 @@ TEST(ArenaTest, GetArenaShouldReturnNullForNonArenaAllocatedMessages) { EXPECT_EQ(NULL, Arena::GetArena(const_pointer_to_message)); } +TEST(ArenaTest, UnsafeSetAllocatedOnArena) { + ::google::protobuf::Arena arena; + TestAllTypes* message = Arena::CreateMessage<TestAllTypes>(&arena); + EXPECT_FALSE(message->has_optional_string()); + + string owned_string = "test with long enough content to heap-allocate"; + message->unsafe_arena_set_allocated_optional_string(&owned_string); + EXPECT_TRUE(message->has_optional_string()); + + message->unsafe_arena_set_allocated_optional_string(NULL); + EXPECT_FALSE(message->has_optional_string()); +} + // A helper utility class to only contain static hook functions, some // counters to be used to verify the counters have been called and a cookie // value to be verified. @@ -1124,6 +1182,13 @@ class ArenaHooksTestUtil { return static_cast<void*>(cookie); } + static void on_allocation(const std::type_info* /*unused*/, uint64 alloc_size, + void* cookie) { + ++num_allocations; + int cookie_value = *static_cast<int*>(cookie); + EXPECT_EQ(kCookieValue, cookie_value); + } + static void on_reset(::google::protobuf::Arena* arena, void* cookie, uint64 space_used) { ++num_reset; @@ -1141,10 +1206,12 @@ class ArenaHooksTestUtil { static const int kCookieValue = 999; static uint32 num_init; + static uint32 num_allocations; static uint32 num_reset; static uint32 num_destruct; }; uint32 ArenaHooksTestUtil::num_init = 0; +uint32 ArenaHooksTestUtil::num_allocations = 0; uint32 ArenaHooksTestUtil::num_reset = 0; uint32 ArenaHooksTestUtil::num_destruct = 0; const int ArenaHooksTestUtil::kCookieValue; @@ -1153,6 +1220,7 @@ const int ArenaHooksTestUtil::kCookieValue; TEST(ArenaTest, ArenaHooksSanity) { ::google::protobuf::ArenaOptions options; options.on_arena_init = ArenaHooksTestUtil::on_init; + options.on_arena_allocation = ArenaHooksTestUtil::on_allocation; options.on_arena_reset = ArenaHooksTestUtil::on_reset; options.on_arena_destruction = ArenaHooksTestUtil::on_destruction; @@ -1160,7 +1228,13 @@ TEST(ArenaTest, ArenaHooksSanity) { { ::google::protobuf::Arena arena(options); EXPECT_EQ(1, ArenaHooksTestUtil::num_init); - + EXPECT_EQ(0, ArenaHooksTestUtil::num_allocations); + ::google::protobuf::Arena::Create<uint64>(&arena); + if (::google::protobuf::internal::has_trivial_destructor<uint64>::value) { + EXPECT_EQ(1, ArenaHooksTestUtil::num_allocations); + } else { + EXPECT_EQ(2, ArenaHooksTestUtil::num_allocations); + } arena.Reset(); arena.Reset(); EXPECT_EQ(2, ArenaHooksTestUtil::num_reset); diff --git a/src/google/protobuf/compiler/code_generator.h b/src/google/protobuf/compiler/code_generator.h index 321a8ccd..b989f151 100644 --- a/src/google/protobuf/compiler/code_generator.h +++ b/src/google/protobuf/compiler/code_generator.h @@ -79,6 +79,37 @@ class LIBPROTOC_EXPORT CodeGenerator { GeneratorContext* generator_context, string* error) const = 0; + // Generates code for all given proto files, generating one or more files in + // the given output directory. + // + // This method should be called instead of |Generate()| when + // |HasGenerateAll()| returns |true|. It is used to emulate legacy semantics + // when more than one `.proto` file is specified on one compiler invocation. + // + // WARNING: Please do not use unless legacy semantics force the code generator + // to produce a single output file for all input files, or otherwise require + // an examination of all input files first. The canonical code generator + // design produces one output file 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 vector<const FileDescriptor*>& files, + const string& parameter, + GeneratorContext* generator_context, + string* error) const { + *error = "Unimplemented GenerateAll() method."; + return false; + } + + // Returns true if the code generator expects to receive all FileDescriptors + // at once (via |GenerateAll()|), rather than one at a time (via + // |Generate()|). This is required to implement legacy semantics. + virtual bool HasGenerateAll() const { return false; } + private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodeGenerator); }; diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc index 567238ae..667b2b63 100644 --- a/src/google/protobuf/compiler/command_line_interface.cc +++ b/src/google/protobuf/compiler/command_line_interface.cc @@ -181,6 +181,68 @@ bool TryCreateParentDirectory(const string& prefix, const string& filename) { return true; } +// Get the absolute path of this protoc binary. +bool GetProtocAbsolutePath(string* path) { +#ifdef _WIN32 + char buffer[MAX_PATH]; + int len = GetModuleFileName(NULL, buffer, MAX_PATH); +#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 string& path) { + // Checking the descriptor.proto file should be good enough. + string file_path = path + "/google/protobuf/descriptor.proto"; + return access(file_path.c_str(), F_OK) != -1; +} + +// Add the paths where google/protobuf/descritor.proto and other well-known +// type protos are installed. +void AddDefaultProtoPaths(vector<pair<string, 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. + string path; + if (!GetProtocAbsolutePath(&path)) { + return; + } + // Strip the binary name. + size_t pos = path.find_last_of("/\\"); + if (pos == string::npos || pos == 0) { + return; + } + path = path.substr(0, pos); + // Check the binary's directory. + if (IsInstalledProtoPath(path)) { + paths->push_back(pair<string, string>("", path)); + return; + } + // Check if there is an include subdirectory. + if (IsInstalledProtoPath(path + "/include")) { + paths->push_back(pair<string, string>("", path + "/include")); + return; + } + // Check if the upper level directory has an "include" subdirectory. + pos = path.find_last_of("/\\"); + if (pos == string::npos || pos == 0) { + return; + } + path = path.substr(0, pos); + if (IsInstalledProtoPath(path + "/include")) { + paths->push_back(pair<string, string>("", path + "/include")); + return; + } +} } // namespace // A MultiFileErrorCollector that prints errors to stderr. @@ -644,6 +706,8 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) { break; } + AddDefaultProtoPaths(&proto_path_); + // Set up the source tree. DiskSourceTree source_tree; for (int i = 0; i < proto_path_.size(); i++) { @@ -898,12 +962,14 @@ CommandLineInterface::ParseArguments(int argc, const char* const argv[]) { return PARSE_ARGUMENT_FAIL; } if (mode_ != MODE_COMPILE && !dependency_out_name_.empty()) { - cerr << "Can only use --dependency_out=FILE when generating code." << endl; + std::cerr << "Can only use --dependency_out=FILE when generating code." + << std::endl; return PARSE_ARGUMENT_FAIL; } if (!dependency_out_name_.empty() && input_files_.size() > 1) { - cerr << "Can only process one input file when using --dependency_out=FILE." - << endl; + 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_name_.empty()) { @@ -1054,11 +1120,11 @@ CommandLineInterface::InterpretArgument(const string& name, } else if (name == "--dependency_out") { if (!dependency_out_name_.empty()) { - cerr << name << " may only be passed once." << endl; + std::cerr << name << " may only be passed once." << std::endl; return PARSE_ARGUMENT_FAIL; } if (value.empty()) { - cerr << name << " requires a non-empty value." << endl; + std::cerr << name << " requires a non-empty value." << std::endl; return PARSE_ARGUMENT_FAIL; } dependency_out_name_ = value; @@ -1272,7 +1338,8 @@ void CommandLineInterface::PrintHelpText() { " defined in the given proto files. Groups share\n" " the same field number space with the parent \n" " message. Extension ranges are counted as \n" -" occupied fields numbers." << std::endl; +" occupied fields numbers." + << std::endl; if (!plugin_prefix_.empty()) { std::cerr << " --plugin=EXECUTABLE Specifies a plugin executable to use.\n" @@ -1327,13 +1394,23 @@ bool CommandLineInterface::GenerateOutput( } parameters.append(generator_parameters_[output_directive.name]); } - for (int i = 0; i < parsed_files.size(); i++) { - if (!output_directive.generator->Generate(parsed_files[i], parameters, - generator_context, &error)) { - // Generator returned an error. - std::cerr << output_directive.name << ": " << parsed_files[i]->name() - << ": " << error << std::endl; - return false; + if (output_directive.generator->HasGenerateAll()) { + 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; + } + } else { + for (int i = 0; i < parsed_files.size(); i++) { + if (!output_directive.generator->Generate(parsed_files[i], parameters, + generator_context, &error)) { + // Generator returned an error. + std::cerr << output_directive.name << ": " << parsed_files[i]->name() + << ": " << error << std::endl; + return false; + } } } } @@ -1403,7 +1480,8 @@ bool CommandLineInterface::GenerateDependencyManifestFile( printer.Print(" $disk_file$", "disk_file", disk_file); if (i < file_set.file_size() - 1) printer.Print("\\\n"); } else { - cerr << "Unable to identify path for file " << virtual_file << endl; + std::cerr << "Unable to identify path for file " << virtual_file + << std::endl; return false; } } @@ -1673,6 +1751,10 @@ void GatherOccupiedFieldRanges(const Descriptor* descriptor, 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) { diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc index a2cbbdc6..e5b77c33 100644 --- a/src/google/protobuf/compiler/command_line_interface_unittest.cc +++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc @@ -115,10 +115,15 @@ class CommandLineInterfaceTest : public testing::Test { // Create a subdirectory within temp_directory_. void CreateTempDir(const 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 void SetInputsAreProtoPathRelative(bool enable) { cli_.SetInputsAreProtoPathRelative(enable); @@ -288,6 +293,7 @@ void CommandLineInterfaceTest::Run(const string& command) { if (!disallow_plugins_) { cli_.AllowPlugins("prefix-"); +#ifndef GOOGLE_THIRD_PARTY_PROTOBUF 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. @@ -316,6 +322,11 @@ void CommandLineInterfaceTest::Run(const string& command) { } if (plugin_path.empty()) { +#else + string plugin_path = "third_party/protobuf/test_plugin"; + + if (access(plugin_path.c_str(), F_OK) != 0) { +#endif // GOOGLE_THIRD_PARTY_PROTOBUF GOOGLE_LOG(ERROR) << "Plugin executable not found. Plugin tests are likely to fail."; } else { @@ -962,6 +973,9 @@ TEST_F(CommandLineInterfaceTest, WriteTransitiveDescriptorSetWithSourceInfo) { 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" @@ -980,6 +994,7 @@ TEST_F(CommandLineInterfaceTest, WriteDependencyManifestFileGivenTwoInputs) { "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" @@ -1005,6 +1020,10 @@ TEST_F(CommandLineInterfaceTest, WriteDependencyManifestFile) { 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", @@ -1026,6 +1045,7 @@ TEST_F(CommandLineInterfaceTest, WriteDependencyManifestFileForAbsolutePath) { "$tmpdir/bar.proto.MockCodeGenerator.test_generator: " "$tmpdir/foo.proto\\\n $tmpdir/bar.proto"); } +#endif // !_WIN32 // ------------------------------------------------------------------- diff --git a/src/google/protobuf/compiler/cpp/cpp_enum.cc b/src/google/protobuf/compiler/cpp/cpp_enum.cc index 3eb20ab1..70d3a600 100644 --- a/src/google/protobuf/compiler/cpp/cpp_enum.cc +++ b/src/google/protobuf/compiler/cpp/cpp_enum.cc @@ -70,12 +70,23 @@ EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor, EnumGenerator::~EnumGenerator() {} +void EnumGenerator::GenerateForwardDeclaration(io::Printer* printer) { + if (!options_.proto_h) { + return; + } + map<string, string> vars; + vars["classname"] = classname_; + printer->Print(vars, "enum $classname$ : int;\n"); + printer->Print(vars, "bool $classname$_IsValid(int value);\n"); +} + void EnumGenerator::GenerateDefinition(io::Printer* printer) { map<string, string> vars; vars["classname"] = classname_; vars["short_name"] = descriptor_->name(); + vars["enumbase"] = classname_ + (options_.proto_h ? " : int" : ""); - printer->Print(vars, "enum $classname$ {\n"); + printer->Print(vars, "enum $enumbase$ {\n"); printer->Indent(); const EnumValueDescriptor* min_value = descriptor_->value(0); @@ -90,7 +101,6 @@ void EnumGenerator::GenerateDefinition(io::Printer* printer) { vars["prefix"] = (descriptor_->containing_type() == NULL) ? "" : classname_ + "_"; - if (i > 0) printer->Print(",\n"); printer->Print(vars, "$prefix$$name$ = $number$"); diff --git a/src/google/protobuf/compiler/cpp/cpp_enum.h b/src/google/protobuf/compiler/cpp/cpp_enum.h index 1ebd7cf7..3e930856 100644 --- a/src/google/protobuf/compiler/cpp/cpp_enum.h +++ b/src/google/protobuf/compiler/cpp/cpp_enum.h @@ -60,6 +60,12 @@ class EnumGenerator { // Header stuff. + // Generate header code to forward-declare the enum. This is for use when + // generating other .proto.h files. This code should be placed within the + // enum's package namespace, but NOT within any class, even for nested + // enums. + void GenerateForwardDeclaration(io::Printer* printer); + // 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. diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc index 74989703..965327b1 100644 --- a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc @@ -242,7 +242,7 @@ void RepeatedEnumFieldGenerator:: GeneratePrivateMembers(io::Printer* printer) const { printer->Print(variables_, "::google::protobuf::RepeatedField<int> $name$_;\n"); - if (descriptor_->options().packed() + if (descriptor_->is_packed() && HasGeneratedMethods(descriptor_->file())) { printer->Print(variables_, "mutable int _$name$_cached_byte_size_;\n"); @@ -352,7 +352,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) const { void RepeatedEnumFieldGenerator:: GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const { - if (!descriptor_->options().packed()) { + if (!descriptor_->is_packed()) { // This path is rarely executed, so we use a non-inlined implementation. if (HasPreservingUnknownEnumSemantics(descriptor_->file())) { printer->Print(variables_, @@ -419,7 +419,7 @@ GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const { void RepeatedEnumFieldGenerator:: GenerateSerializeWithCachedSizes(io::Printer* printer) const { - if (descriptor_->options().packed()) { + if (descriptor_->is_packed()) { // Write the tag and the size. printer->Print(variables_, "if (this->$name$_size() > 0) {\n" @@ -432,7 +432,7 @@ GenerateSerializeWithCachedSizes(io::Printer* printer) const { } printer->Print(variables_, "for (int i = 0; i < this->$name$_size(); i++) {\n"); - if (descriptor_->options().packed()) { + if (descriptor_->is_packed()) { printer->Print(variables_, " ::google::protobuf::internal::WireFormatLite::WriteEnumNoTag(\n" " this->$name$(i), output);\n"); @@ -446,7 +446,7 @@ GenerateSerializeWithCachedSizes(io::Printer* printer) const { void RepeatedEnumFieldGenerator:: GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { - if (descriptor_->options().packed()) { + if (descriptor_->is_packed()) { // Write the tag and the size. printer->Print(variables_, "if (this->$name$_size() > 0) {\n" @@ -460,7 +460,7 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { } printer->Print(variables_, "for (int i = 0; i < this->$name$_size(); i++) {\n"); - if (descriptor_->options().packed()) { + if (descriptor_->is_packed()) { printer->Print(variables_, " target = ::google::protobuf::internal::WireFormatLite::WriteEnumNoTagToArray(\n" " this->$name$(i), target);\n"); @@ -484,7 +484,7 @@ GenerateByteSize(io::Printer* printer) const { " this->$name$(i));\n" "}\n"); - if (descriptor_->options().packed()) { + if (descriptor_->is_packed()) { printer->Print(variables_, "if (data_size > 0) {\n" " total_size += $tag_size$ +\n" diff --git a/src/google/protobuf/compiler/cpp/cpp_field.h b/src/google/protobuf/compiler/cpp/cpp_field.h index cd2b6b75..1d7f8233 100644 --- a/src/google/protobuf/compiler/cpp/cpp_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_field.h @@ -82,12 +82,38 @@ class FieldGenerator { // implementation is empty. virtual void GenerateStaticMembers(io::Printer* /*printer*/) const {} + // Generate prototypes for accessors that will manipulate imported + // messages inline. These are for .proto.h headers. + // + // In .proto.h mode, the headers of imports are not #included. However, + // functions that manipulate the imported message types need access to + // the class definition of the imported message, meaning that the headers + // must be #included. To get around this, functions that manipulate + // imported message objects are defined as dependent functions in a base + // template class. By making them dependent template functions, the + // function templates will not be instantiated until they are called, so + // we can defer to those translation units to #include the necessary + // generated headers. + // + // See: + // http://en.cppreference.com/w/cpp/language/class_template#Implicit_instantiation + // + // Most field types don't need this, so the default implementation is empty. + virtual void GenerateDependentAccessorDeclarations( + 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 depenent accessor functions for this field. + // These are placed inside the header after all class definitions. + virtual void GenerateDependentInlineAccessorDefinitions( + io::Printer* printer) const {} + // Generate inline definitions of accessor functions for this field. // These are placed inside the header after all class definitions. + // In non-.proto.h mode, this generates dependent accessor functions as well. virtual void GenerateInlineAccessorDefinitions( io::Printer* printer, bool is_inline) const = 0; diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc index a98c7d92..b997a51a 100644 --- a/src/google/protobuf/compiler/cpp/cpp_file.cc +++ b/src/google/protobuf/compiler/cpp/cpp_file.cc @@ -94,113 +94,10 @@ FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options) FileGenerator::~FileGenerator() {} void FileGenerator::GenerateHeader(io::Printer* printer) { - string filename_identifier = FilenameIdentifier(file_->name()); - - // Generate top of header. - printer->Print( - "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" - "// source: $filename$\n" - "\n" - "#ifndef PROTOBUF_$filename_identifier$__INCLUDED\n" - "#define PROTOBUF_$filename_identifier$__INCLUDED\n" - "\n" - "#include <string>\n" - "\n", - "filename", file_->name(), - "filename_identifier", filename_identifier); - - - printer->Print( - "#include <google/protobuf/stubs/common.h>\n" - "\n"); - - // Verify the protobuf library header version is compatible with the protoc - // version before going any further. - printer->Print( - "#if GOOGLE_PROTOBUF_VERSION < $min_header_version$\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 $protoc_version$ < GOOGLE_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", - "min_header_version", - SimpleItoa(protobuf::internal::kMinHeaderVersionForProtoc), - "protoc_version", SimpleItoa(GOOGLE_PROTOBUF_VERSION)); - - // OK, it's now safe to #include other files. - printer->Print( - "#include <google/protobuf/arena.h>\n" - "#include <google/protobuf/arenastring.h>\n" - "#include <google/protobuf/generated_message_util.h>\n"); - if (UseUnknownFieldSet(file_)) { - printer->Print( - "#include <google/protobuf/metadata.h>\n"); - } - if (file_->message_type_count() > 0) { - if (HasDescriptorMethods(file_)) { - printer->Print( - "#include <google/protobuf/message.h>\n"); - } else { - printer->Print( - "#include <google/protobuf/message_lite.h>\n"); - } - } - printer->Print( - "#include <google/protobuf/repeated_field.h>\n" - "#include <google/protobuf/extension_set.h>\n"); - if (HasMapFields(file_)) { - printer->Print( - "#include <google/protobuf/map.h>\n"); - if (HasDescriptorMethods(file_)) { - printer->Print( - "#include <google/protobuf/map_field_inl.h>\n"); - } else { - printer->Print( - "#include <google/protobuf/map_field_lite.h>\n"); - } - } - - if (HasEnumDefinitions(file_)) { - if (HasDescriptorMethods(file_)) { - printer->Print( - "#include <google/protobuf/generated_enum_reflection.h>\n"); - } else { - printer->Print( - "#include <google/protobuf/generated_enum_util.h>\n"); - } - } - - if (HasGenericServices(file_)) { - printer->Print( - "#include <google/protobuf/service.h>\n"); - } - - if (UseUnknownFieldSet(file_) && file_->message_type_count() > 0) { - printer->Print( - "#include <google/protobuf/unknown_field_set.h>\n"); - } - - - set<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 string& name = file_->dependency(i)->name(); - bool public_import = (public_import_names.count(name) != 0); + GenerateTopHeaderGuard(printer); - - printer->Print( - "#include \"$dependency$.pb.h\"$iwyu$\n", - "dependency", StripProto(name), - "iwyu", (public_import) ? " // IWYU pragma: export" : ""); - } + GenerateLibraryIncludes(printer); + GenerateDependencyIncludes(printer); printer->Print( "// @@protoc_insertion_point(includes)\n"); @@ -210,132 +107,44 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { // Open namespace. GenerateNamespaceOpeners(printer); - // Forward-declare the AddDescriptors, AssignDescriptors, and ShutdownFile - // functions, so that we can declare them to be friends of each class. - printer->Print( - "\n" - "// Internal implementation detail -- do not call these.\n" - "void $dllexport_decl$$adddescriptorsname$();\n", - "adddescriptorsname", GlobalAddDescriptorsName(file_->name()), - "dllexport_decl", - options_.dllexport_decl.empty() ? "" : options_.dllexport_decl + " "); - - printer->Print( - // Note that we don't put dllexport_decl on these because they are only - // called by the .pb.cc file in which they are defined. - "void $assigndescriptorsname$();\n" - "void $shutdownfilename$();\n" - "\n", - "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()), - "shutdownfilename", GlobalShutdownFileName(file_->name())); - - // Generate forward declarations of classes. - for (int i = 0; i < file_->message_type_count(); i++) { - message_generators_[i]->GenerateForwardDeclaration(printer); - } + GenerateGlobalStateFunctionDeclarations(printer); + GenerateMessageForwardDeclarations(printer); printer->Print("\n"); - // Generate enum definitions. - for (int i = 0; i < file_->message_type_count(); i++) { - message_generators_[i]->GenerateEnumDefinitions(printer); - } - for (int i = 0; i < file_->enum_type_count(); i++) { - enum_generators_[i]->GenerateDefinition(printer); - } + GenerateEnumDefinitions(printer); printer->Print(kThickSeparator); printer->Print("\n"); - // Generate class definitions. - for (int i = 0; i < file_->message_type_count(); i++) { - if (i > 0) { - printer->Print("\n"); - printer->Print(kThinSeparator); - printer->Print("\n"); - } - message_generators_[i]->GenerateClassDefinition(printer); - } + GenerateMessageDefinitions(printer); printer->Print("\n"); printer->Print(kThickSeparator); printer->Print("\n"); - if (HasGenericServices(file_)) { - // Generate service definitions. - for (int i = 0; i < file_->service_count(); i++) { - if (i > 0) { - printer->Print("\n"); - printer->Print(kThinSeparator); - printer->Print("\n"); - } - service_generators_[i]->GenerateDeclarations(printer); - } - - printer->Print("\n"); - printer->Print(kThickSeparator); - printer->Print("\n"); - } + GenerateServiceDefinitions(printer); - // Declare extension identifiers. - for (int i = 0; i < file_->extension_count(); i++) { - extension_generators_[i]->GenerateDeclaration(printer); - } + GenerateExtensionIdentifiers(printer); printer->Print("\n"); printer->Print(kThickSeparator); printer->Print("\n"); - printer->Print("#if !PROTOBUF_INLINE_NOT_IN_HEADERS\n"); - // Generate class inline methods. - for (int i = 0; i < file_->message_type_count(); i++) { - if (i > 0) { - printer->Print(kThinSeparator); - printer->Print("\n"); - } - message_generators_[i]->GenerateInlineMethods(printer, - /* is_inline = */ true); - } - printer->Print("#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS\n"); - - printer->Print( - "\n" - "// @@protoc_insertion_point(namespace_scope)\n"); + GenerateInlineFunctionDefinitions(printer); // Close up namespace. GenerateNamespaceClosers(printer); - // Emit GetEnumDescriptor specializations into google::protobuf namespace: - if (HasEnumDefinitions(file_)) { - // The SWIG conditional is to avoid a null-pointer dereference - // (bug 1984964) in swig-1.3.21 resulting from the following syntax: - // namespace X { void Y<Z::W>(); } - // which appears in GetEnumDescriptor() specializations. - printer->Print( - "\n" - "#ifndef SWIG\n" - "namespace google {\nnamespace protobuf {\n" - "\n"); - for (int i = 0; i < file_->message_type_count(); i++) { - message_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer); - } - for (int i = 0; i < file_->enum_type_count(); i++) { - enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer); - } - printer->Print( - "\n" - "} // namespace protobuf\n} // namespace google\n" - "#endif // SWIG\n"); - } + // We need to specialize some templates in the ::google::protobuf namespace: + GenerateProto2NamespaceEnumSpecializations(printer); printer->Print( "\n" "// @@protoc_insertion_point(global_scope)\n" "\n"); - printer->Print( - "#endif // PROTOBUF_$filename_identifier$__INCLUDED\n", - "filename_identifier", filename_identifier); + GenerateBottomHeaderGuard(printer); } void FileGenerator::GenerateSource(io::Printer* printer) { @@ -707,6 +516,294 @@ void FileGenerator::GenerateNamespaceClosers(io::Printer* printer) { } } +void FileGenerator::GenerateTopHeaderGuard(io::Printer* printer) { + string filename_identifier = FilenameIdentifier(file_->name()); + // Generate top of header. + printer->Print( + "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" + "// source: $filename$\n" + "\n" + "#ifndef PROTOBUF_$filename_identifier$__INCLUDED\n" + "#define PROTOBUF_$filename_identifier$__INCLUDED\n" + "\n" + "#include <string>\n" + "\n", + "filename", file_->name(), + "filename_identifier", filename_identifier); +} + +void FileGenerator::GenerateBottomHeaderGuard(io::Printer* printer) { + string filename_identifier = FilenameIdentifier(file_->name()); + printer->Print( + "#endif // PROTOBUF_$filename_identifier$__INCLUDED\n", + "filename_identifier", filename_identifier); +} + +void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) { + + printer->Print( + "#include <google/protobuf/stubs/common.h>\n" + "\n"); + + // Verify the protobuf library header version is compatible with the protoc + // version before going any further. + printer->Print( + "#if GOOGLE_PROTOBUF_VERSION < $min_header_version$\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 $protoc_version$ < GOOGLE_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", + "min_header_version", + SimpleItoa(protobuf::internal::kMinHeaderVersionForProtoc), + "protoc_version", SimpleItoa(GOOGLE_PROTOBUF_VERSION)); + + // OK, it's now safe to #include other files. + printer->Print( + "#include <google/protobuf/arena.h>\n" + "#include <google/protobuf/arenastring.h>\n" + "#include <google/protobuf/generated_message_util.h>\n"); + if (UseUnknownFieldSet(file_)) { + printer->Print( + "#include <google/protobuf/metadata.h>\n"); + } + if (file_->message_type_count() > 0) { + if (HasDescriptorMethods(file_)) { + printer->Print( + "#include <google/protobuf/message.h>\n"); + } else { + printer->Print( + "#include <google/protobuf/message_lite.h>\n"); + } + } + printer->Print( + "#include <google/protobuf/repeated_field.h>\n" + "#include <google/protobuf/extension_set.h>\n"); + if (HasMapFields(file_)) { + printer->Print( + "#include <google/protobuf/map.h>\n"); + if (HasDescriptorMethods(file_)) { + printer->Print( + "#include <google/protobuf/map_field_inl.h>\n"); + } else { + printer->Print( + "#include <google/protobuf/map_field_lite.h>\n"); + } + } + + if (HasEnumDefinitions(file_)) { + if (HasDescriptorMethods(file_)) { + printer->Print( + "#include <google/protobuf/generated_enum_reflection.h>\n"); + } else { + printer->Print( + "#include <google/protobuf/generated_enum_util.h>\n"); + } + } + + if (HasGenericServices(file_)) { + printer->Print( + "#include <google/protobuf/service.h>\n"); + } + + if (UseUnknownFieldSet(file_) && file_->message_type_count() > 0) { + printer->Print( + "#include <google/protobuf/unknown_field_set.h>\n"); + } + + + if (IsAnyMessage(file_)) { + printer->Print( + "#include \"google/protobuf/any.h\"\n"); + } +} + +void FileGenerator::GenerateDependencyIncludes(io::Printer* printer) { + set<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 string& name = file_->dependency(i)->name(); + bool public_import = (public_import_names.count(name) != 0); + + + printer->Print( + "#include \"$dependency$.pb.h\"$iwyu$\n", + "dependency", StripProto(name), + "iwyu", (public_import) ? " // IWYU pragma: export" : ""); + } +} + +void FileGenerator::GenerateGlobalStateFunctionDeclarations( + io::Printer* printer) { + // Forward-declare the AddDescriptors, AssignDescriptors, and ShutdownFile + // functions, so that we can declare them to be friends of each class. + printer->Print( + "\n" + "// Internal implementation detail -- do not call these.\n" + "void $dllexport_decl$$adddescriptorsname$();\n", + "adddescriptorsname", GlobalAddDescriptorsName(file_->name()), + "dllexport_decl", + options_.dllexport_decl.empty() ? "" : options_.dllexport_decl + " "); + + printer->Print( + // Note that we don't put dllexport_decl on these because they are only + // called by the .pb.cc file in which they are defined. + "void $assigndescriptorsname$();\n" + "void $shutdownfilename$();\n" + "\n", + "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()), + "shutdownfilename", GlobalShutdownFileName(file_->name())); +} + +void FileGenerator::GenerateMessageForwardDeclarations(io::Printer* printer) { + // Generate forward declarations of classes. + for (int i = 0; i < file_->message_type_count(); i++) { + message_generators_[i]->GenerateMessageForwardDeclaration(printer); + } +} + +void FileGenerator::GenerateMessageDefinitions(io::Printer* printer) { + // Generate class definitions. + for (int i = 0; i < file_->message_type_count(); i++) { + if (i > 0) { + printer->Print("\n"); + printer->Print(kThinSeparator); + printer->Print("\n"); + } + message_generators_[i]->GenerateClassDefinition(printer); + } +} + +void FileGenerator::GenerateEnumDefinitions(io::Printer* printer) { + // Generate enum definitions. + for (int i = 0; i < file_->message_type_count(); i++) { + message_generators_[i]->GenerateEnumDefinitions(printer); + } + for (int i = 0; i < file_->enum_type_count(); i++) { + enum_generators_[i]->GenerateDefinition(printer); + } +} + +void FileGenerator::GenerateServiceDefinitions(io::Printer* printer) { + if (HasGenericServices(file_)) { + // Generate service definitions. + for (int i = 0; i < file_->service_count(); i++) { + if (i > 0) { + printer->Print("\n"); + printer->Print(kThinSeparator); + printer->Print("\n"); + } + service_generators_[i]->GenerateDeclarations(printer); + } + + printer->Print("\n"); + printer->Print(kThickSeparator); + printer->Print("\n"); + } +} + +void FileGenerator::GenerateExtensionIdentifiers(io::Printer* printer) { + // Declare extension identifiers. + for (int i = 0; i < file_->extension_count(); i++) { + extension_generators_[i]->GenerateDeclaration(printer); + } +} + +void FileGenerator::GenerateInlineFunctionDefinitions(io::Printer* printer) { + // An aside about inline functions in .proto.h mode: + // + // The PROTOBUF_INLINE_NOT_IN_HEADERS symbol controls conditionally + // moving much of the inline functions to the .pb.cc file, which can be a + // significant performance benefit for compilation time, at the expense + // of non-inline function calls. + // + // However, in .proto.h mode, the definition of the internal dependent + // base class must remain in the header, and can never be out-lined. The + // dependent base class also needs access to has-bit manipuation + // functions, so the has-bit functions must be unconditionally inlined in + // proto_h mode. + // + // This gives us three flavors of functions: + // + // 1. Functions on the message not used by the internal dependent base + // class: in .proto.h mode, only some functions are defined on the + // message class; others are defined on the dependent base class. + // These are guarded and can be out-lined. These are generated by + // GenerateInlineMethods, and include has_* bit functions in + // non-proto_h mode. + // + // 2. Functions on the internal dependent base class: these functions + // are dependent on a template parameter, so they always need to + // remain in the header. + // + // 3. Functions on the message that are used by the dependent base: the + // dependent base class down casts itself to the message + // implementation class to access these functions (the has_* bit + // manipulation functions). Unlike #1, these functions must + // unconditionally remain in the header. These are emitted by + // GenerateDependentInlineMethods, even though they are not actually + // dependent. + + printer->Print("#if !PROTOBUF_INLINE_NOT_IN_HEADERS\n"); + // Generate class inline methods. + for (int i = 0; i < file_->message_type_count(); i++) { + if (i > 0) { + printer->Print(kThinSeparator); + printer->Print("\n"); + } + message_generators_[i]->GenerateInlineMethods(printer, + /* is_inline = */ true); + } + printer->Print("#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS\n"); + + for (int i = 0; i < file_->message_type_count(); i++) { + if (i > 0) { + printer->Print(kThinSeparator); + printer->Print("\n"); + } + // Methods of the dependent base class must always be inline in the header. + message_generators_[i]->GenerateDependentInlineMethods(printer); + } + + printer->Print( + "\n" + "// @@protoc_insertion_point(namespace_scope)\n"); +} + +void FileGenerator::GenerateProto2NamespaceEnumSpecializations( + io::Printer* printer) { + // Emit GetEnumDescriptor specializations into google::protobuf namespace: + if (HasEnumDefinitions(file_)) { + // The SWIG conditional is to avoid a null-pointer dereference + // (bug 1984964) in swig-1.3.21 resulting from the following syntax: + // namespace X { void Y<Z::W>(); } + // which appears in GetEnumDescriptor() specializations. + printer->Print( + "\n" + "#ifndef SWIG\n" + "namespace google {\nnamespace protobuf {\n" + "\n"); + for (int i = 0; i < file_->message_type_count(); i++) { + message_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer); + } + for (int i = 0; i < file_->enum_type_count(); i++) { + enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer); + } + printer->Print( + "\n" + "} // namespace protobuf\n} // namespace google\n" + "#endif // SWIG\n"); + } +} + } // namespace cpp } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/cpp/cpp_file.h b/src/google/protobuf/compiler/cpp/cpp_file.h index 0e06547d..e68f67bb 100644 --- a/src/google/protobuf/compiler/cpp/cpp_file.h +++ b/src/google/protobuf/compiler/cpp/cpp_file.h @@ -80,6 +80,35 @@ class FileGenerator { void GenerateNamespaceOpeners(io::Printer* printer); void GenerateNamespaceClosers(io::Printer* printer); + // Generates top or bottom of a header file. + void GenerateTopHeaderGuard(io::Printer* printer); + void GenerateBottomHeaderGuard(io::Printer* printer); + + // Generates #include directives. + void GenerateLibraryIncludes(io::Printer* printer); + void GenerateDependencyIncludes(io::Printer* printer); + + // Generates a couple of different pieces before definitions: + void GenerateGlobalStateFunctionDeclarations(io::Printer* printer); + + // Generates types for classes. + void GenerateMessageForwardDeclarations(io::Printer* printer); + void GenerateMessageDefinitions(io::Printer* printer); + + // Generates enum definitions. + 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 defintions. + void GenerateInlineFunctionDefinitions(io::Printer* printer); + + void GenerateProto2NamespaceEnumSpecializations(io::Printer* printer); + const FileDescriptor* file_; google::protobuf::scoped_array<google::protobuf::scoped_ptr<MessageGenerator> > message_generators_; diff --git a/src/google/protobuf/compiler/cpp/cpp_generator.cc b/src/google/protobuf/compiler/cpp/cpp_generator.cc index c999b93f..99416372 100644 --- a/src/google/protobuf/compiler/cpp/cpp_generator.cc +++ b/src/google/protobuf/compiler/cpp/cpp_generator.cc @@ -82,6 +82,7 @@ bool CppGenerator::Generate(const FileDescriptor* file, // } // FOO_EXPORT is a macro which should expand to __declspec(dllexport) or // __declspec(dllimport) depending on what is being compiled. + // Options file_options; for (int i = 0; i < options.size(); i++) { diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc index 4e7155c3..0f3688d0 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc @@ -51,6 +51,9 @@ namespace cpp { namespace { +static const char kAnyMessageName[] = "Any"; +static const char kAnyProtoFile[] = "google/protobuf/any.proto"; + string DotsToUnderscores(const string& name) { return StringReplace(name, ".", "_", true); } @@ -162,6 +165,10 @@ string ClassName(const EnumDescriptor* enum_descriptor, bool qualified) { } +string DependentBaseClassTemplateName(const Descriptor* descriptor) { + return ClassName(descriptor, false) + "_InternalBase"; +} + string SuperClassName(const Descriptor* descriptor) { return HasDescriptorMethods(descriptor->file()) ? "::google::protobuf::Message" : "::google::protobuf::MessageLite"; @@ -200,6 +207,47 @@ string FieldConstantName(const FieldDescriptor *field) { return result; } +bool IsFieldDependent(const FieldDescriptor* field) { + if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) { + return false; + } + if (field->containing_oneof() != NULL) { + // Oneof fields will always be dependent. + // + // This is a unique case for field codegen. Field generators are + // responsible for generating all the field-specific accessor + // functions, except for the clear_*() function; instead, field + // generators produce inline clearing code. + // + // For non-oneof fields, the Message class uses the inline clearing + // code to define the field's clear_*() function, as well as in the + // destructor. For oneof fields, the Message class generates a much + // more complicated clear_*() function, which clears only the oneof + // member that is set, in addition to clearing methods for each of the + // oneof members individually. + // + // Since oneofs do not have their own generator class, the Message code + // generation logic would be significantly complicated in order to + // split dependent and non-dependent manipulation logic based on + // whether the oneof truly needs to be dependent; so, for oneof fields, + // we just assume it (and its constituents) should be manipulated by a + // dependent base class function. + // + // This is less precise than how dependent message-typed fields are + // handled, but the cost is limited to only the generated code for the + // oneof field, which seems like an acceptable tradeoff. + return true; + } + if (field->file() == field->message_type()->file()) { + return false; + } + return true; +} + +string DependentTypeName(const FieldDescriptor* field) { + return "InternalBase_" + field->name() + "_T"; +} + string FieldMessageTypeName(const FieldDescriptor* field) { // Note: The Google-internal version of Protocol Buffers uses this function // as a hook point for hacks to support legacy code. @@ -360,7 +408,7 @@ string FilenameIdentifier(const string& filename) { } else { // Not alphanumeric. To avoid any possibility of name conflicts we // use the hex code for the character. - StrAppend(&result, "_", ToHex(static_cast<uint8>(filename[i]))); + StrAppend(&result, "_", strings::Hex(static_cast<uint8>(filename[i]))); } } return result; @@ -521,6 +569,15 @@ FieldOptions::CType EffectiveStringCType(const FieldDescriptor* field) { } +bool IsAnyMessage(const FileDescriptor* descriptor) { + return descriptor->name() == kAnyProtoFile; +} + +bool IsAnyMessage(const Descriptor* descriptor) { + return descriptor->name() == kAnyMessageName && + descriptor->file()->name() == kAnyProtoFile; +} + } // namespace cpp } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.h b/src/google/protobuf/compiler/cpp/cpp_helpers.h index 284fa2c1..4bbf8303 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.h +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h @@ -66,6 +66,10 @@ extern const char kThinSeparator[]; string ClassName(const Descriptor* descriptor, bool qualified); string ClassName(const EnumDescriptor* enum_descriptor, bool qualified); +// Name of the CRTP class template (for use with proto_h). +// This is a class name, like "ProtoName_InternalBase". +string DependentBaseClassTemplateName(const Descriptor* descriptor); + string SuperClassName(const Descriptor* descriptor); // Get the (unqualified) name that should be used for this field in C++ code. @@ -88,6 +92,20 @@ inline const Descriptor* FieldScope(const FieldDescriptor* field) { field->extension_scope() : field->containing_type(); } +// Returns true if the given 'field_descriptor' has a message type that is +// a dependency of the file where the field is defined (i.e., the field +// type is defined in a different file than the message holding the field). +// +// This only applies to Message-typed fields. Enum-typed fields may refer +// to an enum in a dependency; however, enums are specified and +// forward-declared with an enum-base, so the definition is not required to +// manipulate the field value. +bool IsFieldDependent(const FieldDescriptor* field_descriptor); + +// Returns the name that should be used for forcing dependent lookup from a +// dependent base class. +string DependentTypeName(const FieldDescriptor* field); + // Returns the fully-qualified type name field->message_type(). Usually this // is just ClassName(field->message_type(), true); string FieldMessageTypeName(const FieldDescriptor* field); @@ -242,6 +260,9 @@ inline bool SupportsArenas(const FieldDescriptor* field) { return SupportsArenas(field->file()); } +bool IsAnyMessage(const FileDescriptor* descriptor); +bool IsAnyMessage(const Descriptor* descriptor); + } // namespace cpp } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.cc b/src/google/protobuf/compiler/cpp/cpp_map_field.cc index 8c38db2b..0ff0d27c 100644 --- a/src/google/protobuf/compiler/cpp/cpp_map_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_map_field.cc @@ -244,7 +244,8 @@ GenerateSerializeWithCachedSizes(io::Printer* printer) const { "{\n" " ::google::protobuf::scoped_ptr<$map_classname$> entry;\n" " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" - " it = $name$().begin(); it != $name$().end(); ++it) {\n"); + " it = this->$name$().begin();\n" + " it != this->$name$().end(); ++it) {\n"); // If entry is allocated by arena, its desctructor should be avoided. if (SupportsArenas(descriptor_)) { @@ -277,7 +278,8 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { "{\n" " ::google::protobuf::scoped_ptr<$map_classname$> entry;\n" " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" - " it = $name$().begin(); it != $name$().end(); ++it) {\n"); + " it = this->$name$().begin();\n" + " it != this->$name$().end(); ++it) {\n"); // If entry is allocated by arena, its desctructor should be avoided. if (SupportsArenas(descriptor_)) { @@ -312,7 +314,8 @@ GenerateByteSize(io::Printer* printer) const { "{\n" " ::google::protobuf::scoped_ptr<$map_classname$> entry;\n" " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n" - " it = $name$().begin(); it != $name$().end(); ++it) {\n"); + " it = this->$name$().begin();\n" + " it != this->$name$().end(); ++it) {\n"); // If entry is allocated by arena, its desctructor should be avoided. if (SupportsArenas(descriptor_)) { diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc index bafa36f5..212fe2e1 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message.cc @@ -64,10 +64,15 @@ using internal::WireFormatLite; namespace { -void PrintFieldComment(io::Printer* printer, const FieldDescriptor* field) { - // Print the field's proto-syntax definition as a comment. We don't want to - // print group bodies so we cut off after the first line. - string def = field->DebugString(); +template <class T> +void PrintFieldComment(io::Printer* printer, 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; + string def = field->DebugStringWithOptions(options); printer->Print("// $def$\n", "def", def.substr(0, def.find_first_of('\n'))); } @@ -280,6 +285,10 @@ void OptimizePadding(vector<const FieldDescriptor*>* fields) { } } +string MessageTypeProtoName(const FieldDescriptor* field) { + return field->message_type()->full_name(); +} + // 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 @@ -379,7 +388,8 @@ MessageGenerator::MessageGenerator(const Descriptor* descriptor, enum_generators_( new google::protobuf::scoped_ptr<EnumGenerator>[descriptor->enum_type_count()]), extension_generators_(new google::protobuf::scoped_ptr< - ExtensionGenerator>[descriptor->extension_count()]) { + ExtensionGenerator>[descriptor->extension_count()]), + use_dependent_base_(false) { for (int i = 0; i < descriptor->nested_type_count(); i++) { nested_generators_[i].reset( @@ -401,13 +411,16 @@ MessageGenerator::MessageGenerator(const Descriptor* descriptor, if (descriptor->field(i)->is_required()) { ++num_required_fields_; } + if (options.proto_h && IsFieldDependent(descriptor->field(i))) { + use_dependent_base_ = true; + } } } MessageGenerator::~MessageGenerator() {} void MessageGenerator:: -GenerateForwardDeclaration(io::Printer* printer) { +GenerateMessageForwardDeclaration(io::Printer* printer) { printer->Print("class $classname$;\n", "classname", classname_); @@ -416,7 +429,17 @@ GenerateForwardDeclaration(io::Printer* printer) { // message cannot be a top level class, we just need to avoid calling // GenerateForwardDeclaration here. if (IsMapEntryMessage(descriptor_->nested_type(i))) continue; - nested_generators_[i]->GenerateForwardDeclaration(printer); + nested_generators_[i]->GenerateMessageForwardDeclaration(printer); + } +} + +void MessageGenerator:: +GenerateEnumForwardDeclaration(io::Printer* printer) { + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + nested_generators_[i]->GenerateEnumForwardDeclaration(printer); + } + for (int i = 0; i < descriptor_->enum_type_count(); i++) { + enum_generators_[i]->GenerateForwardDeclaration(printer); } } @@ -442,6 +465,35 @@ GenerateGetEnumDescriptorSpecializations(io::Printer* printer) { } void MessageGenerator:: +GenerateDependentFieldAccessorDeclarations(io::Printer* printer) { + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + + PrintFieldComment(printer, field); + + map<string, string> vars; + SetCommonFieldVariables(field, &vars, options_); + + if (use_dependent_base_ && IsFieldDependent(field)) { + // If the message is dependent, the inline clear_*() method will need + // to delete the message type, so it must be in the dependent base + // class. (See also GenerateFieldAccessorDeclarations.) + printer->Print(vars, "void clear_$name$()$deprecation$;\n"); + } + // Generate type-specific accessor declarations. + field_generators_.get(field).GenerateDependentAccessorDeclarations(printer); + printer->Print("\n"); + } + for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { + const OneofDescriptor* oneof = descriptor_->oneof_decl(i); + PrintFieldComment(printer, oneof); + printer->Print( + "void clear_$oneof_name$();\n", + "oneof_name", oneof->name()); + } +} + +void MessageGenerator:: GenerateFieldAccessorDeclarations(io::Printer* printer) { for (int i = 0; i < descriptor_->field_count(); i++) { const FieldDescriptor* field = descriptor_->field(i); @@ -452,6 +504,19 @@ GenerateFieldAccessorDeclarations(io::Printer* printer) { SetCommonFieldVariables(field, &vars, options_); vars["constant_name"] = FieldConstantName(field); + bool dependent_field = use_dependent_base_ && IsFieldDependent(field); + if (dependent_field) { + // If this field is dependent, the dependent base class determines + // the message type from the derived class (which is a template + // parameter). This typedef is for that: + printer->Print( + "private:\n" + "typedef $field_type$ $dependent_type$;\n" + "public:\n", + "field_type", FieldMessageTypeName(field), + "dependent_type", DependentTypeName(field)); + } + if (field->is_repeated()) { printer->Print(vars, "int $name$_size() const$deprecation$;\n"); } else if (HasHasMethod(field)) { @@ -463,7 +528,11 @@ GenerateFieldAccessorDeclarations(io::Printer* printer) { "public:\n"); } - printer->Print(vars, "void clear_$name$()$deprecation$;\n"); + if (!dependent_field) { + // If this field is dependent, then its clear_() method is in the + // depenent base class. (See also GenerateDependentAccessorDeclarations.) + printer->Print(vars, "void clear_$name$()$deprecation$;\n"); + } printer->Print(vars, "static const int $constant_name$ = $number$;\n"); // Generate type-specific accessor declarations. @@ -490,6 +559,188 @@ GenerateFieldAccessorDeclarations(io::Printer* printer) { } void MessageGenerator:: +GenerateDependentFieldAccessorDefinitions(io::Printer* printer) { + if (!use_dependent_base_) return; + + printer->Print("// $classname$\n\n", "classname", + DependentBaseClassTemplateName(descriptor_)); + + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + + PrintFieldComment(printer, field); + + // These functions are not really dependent: they are part of the + // (non-dependent) derived class. However, they need to live outside + // any #ifdef guards, so we treat them as if they were dependent. + // + // See the comment in FileGenerator::GenerateInlineFunctionDefinitions + // for a more complete explanation. + if (use_dependent_base_ && IsFieldDependent(field)) { + map<string, string> vars; + SetCommonFieldVariables(field, &vars, options_); + vars["inline"] = "inline "; + if (field->containing_oneof()) { + vars["field_name"] = UnderscoresToCamelCase(field->name(), true); + vars["oneof_name"] = field->containing_oneof()->name(); + vars["oneof_index"] = SimpleItoa(field->containing_oneof()->index()); + GenerateOneofMemberHasBits(field, vars, printer); + } else if (!field->is_repeated()) { + // There will be no header guard, so this always has to be inline. + GenerateSingularFieldHasBits(field, vars, printer); + } + // vars needed for clear_(), which is in the dependent base: + // (See also GenerateDependentFieldAccessorDeclarations.) + vars["tmpl"] = "template<class T>\n"; + vars["dependent_classname"] = + DependentBaseClassTemplateName(descriptor_) + "<T>"; + vars["this_message"] = "reinterpret_cast<T*>(this)->"; + vars["this_const_message"] = "reinterpret_cast<const T*>(this)->"; + GenerateFieldClear(field, vars, printer); + } + + // Generate type-specific accessors. + field_generators_.get(field) + .GenerateDependentInlineAccessorDefinitions(printer); + + printer->Print("\n"); + } + + // Generate has_$name$() and clear_has_$name$() functions for oneofs + // Similar to other has-bits, these must always be in the header if we + // are using a dependent base class. + GenerateOneofHasBits(printer, true /* is_inline */); +} + +void MessageGenerator:: +GenerateSingularFieldHasBits(const FieldDescriptor* field, + map<string, string> vars, + io::Printer* printer) { + if (HasFieldPresence(descriptor_->file())) { + // N.B.: without field presence, we do not use has-bits or generate + // has_$name$() methods. + vars["has_array_index"] = SimpleItoa(field->index() / 32); + vars["has_mask"] = StrCat(strings::Hex(1u << (field->index() % 32), + strings::Hex::ZERO_PAD_8)); + printer->Print(vars, + "$inline$" + "bool $classname$::has_$name$() const {\n" + " return (_has_bits_[$has_array_index$] & 0x$has_mask$u) != 0;\n" + "}\n" + "$inline$" + "void $classname$::set_has_$name$() {\n" + " _has_bits_[$has_array_index$] |= 0x$has_mask$u;\n" + "}\n" + "$inline$" + "void $classname$::clear_has_$name$() {\n" + " _has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n" + "}\n"); + } else { + // Message fields have a has_$name$() method. + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + bool is_lazy = false; + if (is_lazy) { + printer->Print(vars, + "$inline$" + "bool $classname$::has_$name$() const {\n" + " return !$name$_.IsCleared();\n" + "}\n"); + } else { + printer->Print(vars, + "$inline$" + "bool $classname$::has_$name$() const {\n" + " return !_is_default_instance_ && $name$_ != NULL;\n" + "}\n"); + } + } + } +} + +void MessageGenerator:: +GenerateOneofHasBits(io::Printer* printer, bool is_inline) { + for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { + map<string, string> vars; + vars["oneof_name"] = descriptor_->oneof_decl(i)->name(); + vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index()); + vars["cap_oneof_name"] = + ToUpper(descriptor_->oneof_decl(i)->name()); + vars["classname"] = classname_; + vars["inline"] = (is_inline ? "inline " : ""); + printer->Print( + vars, + "$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 map<string, string>& vars, + io::Printer* printer) { + // 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). + printer->Print(vars, + "$inline$" + "bool $classname$::has_$name$() const {\n" + " return $oneof_name$_case() == k$field_name$;\n" + "}\n"); + printer->Print(vars, + "$inline$" + "void $classname$::set_has_$name$() {\n" + " _oneof_case_[$oneof_index$] = k$field_name$;\n" + "}\n"); +} + +void MessageGenerator:: +GenerateFieldClear(const FieldDescriptor* field, + const map<string, string>& vars, + io::Printer* printer) { + // Generate clear_$name$() (See GenerateFieldAccessorDeclarations and + // GenerateDependentFieldAccessorDeclarations, $dependent_classname$ is + // set by the Generate*Definitions functions.) + printer->Print(vars, + "$tmpl$" + "$inline$" + "void $dependent_classname$::clear_$name$() {\n"); + + printer->Indent(); + + if (field->containing_oneof()) { + // Clear this field only if it is the active field in this oneof, + // otherwise ignore + printer->Print(vars, + "if ($this_message$has_$name$()) {\n"); + printer->Indent(); + field_generators_.get(field).GenerateClearingCode(printer); + printer->Print(vars, + "$this_message$clear_has_$oneof_name$();\n"); + printer->Outdent(); + printer->Print("}\n"); + } else { + field_generators_.get(field).GenerateClearingCode(printer); + if (HasFieldPresence(descriptor_->file())) { + if (!field->is_repeated()) { + printer->Print(vars, + "$this_message$clear_has_$name$();\n"); + } + } + } + + printer->Outdent(); + printer->Print("}\n"); +} + +void MessageGenerator:: GenerateFieldAccessorDefinitions(io::Printer* printer, bool is_inline) { printer->Print("// $classname$\n\n", "classname", classname_); @@ -500,101 +751,37 @@ GenerateFieldAccessorDefinitions(io::Printer* printer, bool is_inline) { map<string, string> vars; SetCommonFieldVariables(field, &vars, options_); - vars["inline"] = is_inline ? "inline" : ""; + vars["inline"] = is_inline ? "inline " : ""; // Generate has_$name$() or $name$_size(). if (field->is_repeated()) { printer->Print(vars, - "$inline$ int $classname$::$name$_size() const {\n" + "$inline$" + "int $classname$::$name$_size() const {\n" " return $name$_.size();\n" "}\n"); } else if (field->containing_oneof()) { - // 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). vars["field_name"] = UnderscoresToCamelCase(field->name(), true); vars["oneof_name"] = field->containing_oneof()->name(); vars["oneof_index"] = SimpleItoa(field->containing_oneof()->index()); - printer->Print(vars, - "$inline$ bool $classname$::has_$name$() const {\n" - " return $oneof_name$_case() == k$field_name$;\n" - "}\n"); - printer->Print(vars, - "$inline$ void $classname$::set_has_$name$() {\n" - " _oneof_case_[$oneof_index$] = k$field_name$;\n" - "}\n"); + if (!use_dependent_base_ || !IsFieldDependent(field)) { + GenerateOneofMemberHasBits(field, vars, printer); + } } else { // Singular field. - if (HasFieldPresence(descriptor_->file())) { - // N.B.: without field presence, we do not use has-bits or generate - // has_$name$() methods. - char buffer[kFastToBufferSize]; - vars["has_array_index"] = SimpleItoa(field->index() / 32); - vars["has_mask"] = FastHex32ToBuffer(1u << (field->index() % 32), - buffer); - printer->Print(vars, - "$inline$ bool $classname$::has_$name$() const {\n" - " return (_has_bits_[$has_array_index$] & 0x$has_mask$u) != 0;\n" - "}\n" - "$inline$ void $classname$::set_has_$name$() {\n" - " _has_bits_[$has_array_index$] |= 0x$has_mask$u;\n" - "}\n" - "$inline$ void $classname$::clear_has_$name$() {\n" - " _has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n" - "}\n" - ); - } else { - // Message fields have a has_$name$() method. - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { - bool is_lazy = false; - if (is_lazy) { - printer->Print(vars, - "$inline$ bool $classname$::has_$name$() const {\n" - " return !$name$_.IsCleared();\n" - "}\n"); - } else { - printer->Print(vars, - "$inline$ bool $classname$::has_$name$() const {\n" - " return !_is_default_instance_ && $name$_ != NULL;\n" - "}\n"); - } - } + if (!use_dependent_base_ || !IsFieldDependent(field)) { + GenerateSingularFieldHasBits(field, vars, printer); } } - // Generate clear_$name$() - printer->Print(vars, - "$inline$ void $classname$::clear_$name$() {\n"); - - printer->Indent(); - - if (field->containing_oneof()) { - // Clear this field only if it is the active field in this oneof, - // otherwise ignore - printer->Print(vars, - "if (has_$name$()) {\n"); - printer->Indent(); - field_generators_.get(field).GenerateClearingCode(printer); - printer->Print(vars, - "clear_has_$oneof_name$();\n"); - printer->Outdent(); - printer->Print("}\n"); - } else { - field_generators_.get(field).GenerateClearingCode(printer); - if (HasFieldPresence(descriptor_->file())) { - if (!field->is_repeated()) { - printer->Print(vars, - "clear_has_$name$();\n"); - } - } + if (!use_dependent_base_ || !IsFieldDependent(field)) { + vars["tmpl"] = ""; + vars["dependent_classname"] = vars["classname"]; + vars["this_message"] = ""; + vars["this_const_message"] = ""; + GenerateFieldClear(field, vars, printer); } - printer->Outdent(); - printer->Print("}\n"); - // Generate type-specific accessors. field_generators_.get(field).GenerateInlineAccessorDefinitions(printer, is_inline); @@ -602,23 +789,11 @@ GenerateFieldAccessorDefinitions(io::Printer* printer, bool is_inline) { printer->Print("\n"); } - // Generate has_$name$() and clear_has_$name$() functions for oneofs - for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { - map<string, string> vars; - vars["oneof_name"] = descriptor_->oneof_decl(i)->name(); - vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index()); - vars["cap_oneof_name"] = - ToUpper(descriptor_->oneof_decl(i)->name()); - vars["classname"] = classname_; - vars["inline"] = is_inline ? "inline" : ""; - printer->Print( - vars, - "$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"); + if (!use_dependent_base_) { + // Generate has_$name$() and clear_has_$name$() functions for oneofs + // If we aren't using a dependent base, they can be with the other functions + // that are #ifdef-guarded. + GenerateOneofHasBits(printer, is_inline); } } @@ -648,6 +823,34 @@ static bool CanClearByZeroing(const FieldDescriptor* field) { } void MessageGenerator:: +GenerateDependentBaseClassDefinition(io::Printer* printer) { + if (!use_dependent_base_) { + return; + } + + map<string, string> vars; + vars["classname"] = DependentBaseClassTemplateName(descriptor_); + vars["superclass"] = SuperClassName(descriptor_); + + printer->Print(vars, + "template <class T>\n" + "class $classname$ : public $superclass$ {\n" + " public:\n"); + printer->Indent(); + + printer->Print(vars, + "$classname$() {}\n" + "virtual ~$classname$() {}\n" + "\n"); + + // Generate dependent accessor methods for all fields. + GenerateDependentFieldAccessorDeclarations(printer); + + printer->Outdent(); + printer->Print("};\n"); +} + +void MessageGenerator:: GenerateClassDefinition(io::Printer* printer) { for (int i = 0; i < descriptor_->nested_type_count(); i++) { // map entry message doesn't need class definition. Since map entry message @@ -660,6 +863,11 @@ GenerateClassDefinition(io::Printer* printer) { printer->Print("\n"); } + if (use_dependent_base_) { + GenerateDependentBaseClassDefinition(printer); + printer->Print("\n"); + } + map<string, string> vars; vars["classname"] = classname_; vars["field_count"] = SimpleItoa(descriptor_->field_count()); @@ -669,11 +877,18 @@ GenerateClassDefinition(io::Printer* printer) { } else { vars["dllexport"] = options_.dllexport_decl + " "; } - vars["superclass"] = SuperClassName(descriptor_); - + if (use_dependent_base_) { + vars["superclass"] = + DependentBaseClassTemplateName(descriptor_) + "<" + classname_ + ">"; + } else { + vars["superclass"] = SuperClassName(descriptor_); + } printer->Print(vars, - "class $dllexport$$classname$ : public $superclass$ {\n" - " public:\n"); + "class $dllexport$$classname$ : public $superclass$ {\n"); + if (use_dependent_base_) { + printer->Print(vars, " friend class $superclass$;\n"); + } + printer->Print(" public:\n"); printer->Indent(); printer->Print(vars, @@ -782,6 +997,19 @@ GenerateClassDefinition(io::Printer* printer) { printer->Print(vars, "void UnsafeArenaSwap($classname$* other);\n"); } + + if (IsAnyMessage(descriptor_)) { + printer->Print(vars, + "// implements Any -----------------------------------------------\n" + "\n" + "void PackFrom(const ::google::protobuf::Message& message);\n" + "bool UnpackTo(::google::protobuf::Message* message) const;\n" + "template<typename T> bool Is() const {\n" + " return _any_metadata_.Is<T>();\n" + "}\n" + "\n"); + } + printer->Print(vars, "void Swap($classname$* other);\n" "\n" @@ -973,11 +1201,18 @@ GenerateClassDefinition(io::Printer* printer) { // Generate oneof function declarations for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { - printer->Print( - "inline bool has_$oneof_name$() const;\n" - "void clear_$oneof_name$();\n" - "inline void clear_has_$oneof_name$();\n\n", - "oneof_name", descriptor_->oneof_decl(i)->name()); + if (use_dependent_base_) { + printer->Print( + "inline bool has_$oneof_name$() const;\n" + "inline void clear_has_$oneof_name$();\n\n", + "oneof_name", descriptor_->oneof_decl(i)->name()); + } else { + printer->Print( + "inline bool has_$oneof_name$() const;\n" + "void clear_$oneof_name$();\n" + "inline void clear_has_$oneof_name$();\n\n", + "oneof_name", descriptor_->oneof_decl(i)->name()); + } } if (HasGeneratedMethods(descriptor_->file()) && @@ -1139,6 +1374,12 @@ GenerateClassDefinition(io::Printer* printer) { "\n"); } + // Generate _any_metadata_ for the Any type. + if (IsAnyMessage(descriptor_)) { + printer->Print(vars, + "::google::protobuf::internal::AnyMetadata _any_metadata_;\n"); + } + // Declare AddDescriptors(), BuildDescriptors(), and ShutdownFile() as // friends so that they can access private static variables like // default_instance_ and reflection_. @@ -1172,6 +1413,21 @@ GenerateClassDefinition(io::Printer* printer) { } void MessageGenerator:: +GenerateDependentInlineMethods(io::Printer* printer) { + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + // map entry message doesn't need inline methods. Since map entry message + // cannot be a top level class, we just need to avoid calling + // GenerateInlineMethods here. + if (IsMapEntryMessage(descriptor_->nested_type(i))) continue; + nested_generators_[i]->GenerateDependentInlineMethods(printer); + printer->Print(kThinSeparator); + printer->Print("\n"); + } + + GenerateDependentFieldAccessorDefinitions(printer); +} + +void MessageGenerator:: GenerateInlineMethods(io::Printer* printer, bool is_inline) { for (int i = 0; i < descriptor_->nested_type_count(); i++) { // map entry message doesn't need inline methods. Since map entry message @@ -1196,7 +1452,8 @@ GenerateInlineMethods(io::Printer* printer, bool is_inline) { vars["inline"] = is_inline ? "inline " : ""; printer->Print( vars, - "$inline$$class_name$::$camel_oneof_name$Case $class_name$::" + "$inline$" + "$class_name$::$camel_oneof_name$Case $class_name$::" "$oneof_name$_case() const {\n" " return $class_name$::$camel_oneof_name$Case(" "_oneof_case_[$oneof_index$]);\n" @@ -1494,6 +1751,19 @@ GenerateShutdownCode(io::Printer* printer) { void MessageGenerator:: GenerateClassMethods(io::Printer* printer) { + if (IsAnyMessage(descriptor_)) { + printer->Print( + "void $classname$::PackFrom(const ::google::protobuf::Message& message) {\n" + " _any_metadata_.PackFrom(message);\n" + "}\n" + "\n" + "bool $classname$::UnpackTo(::google::protobuf::Message* message) const {\n" + " return _any_metadata_.UnpackTo(message);\n" + "}\n" + "\n", + "classname", classname_); + } + for (int i = 0; i < descriptor_->enum_type_count(); i++) { enum_generators_[i]->GenerateMethods(printer); } @@ -1767,7 +2037,7 @@ GenerateArenaDestructorCode(io::Printer* printer) { if (need_registration) { printer->Print( "inline void $classname$::RegisterArenaDtor(::google::protobuf::Arena* arena) {\n" - " if (arena != NULL) {" + " if (arena != NULL) {\n" " arena->OwnCustomDestructor(this, &$classname$::ArenaDtor);\n" " }\n" "}\n", @@ -1782,18 +2052,23 @@ GenerateArenaDestructorCode(io::Printer* printer) { void MessageGenerator:: GenerateStructors(io::Printer* printer) { - string superclass = SuperClassName(descriptor_); - string initializer_with_arena; - if (UseUnknownFieldSet(descriptor_->file())) { - initializer_with_arena = "_internal_metadata_(arena)"; + string superclass; + if (use_dependent_base_) { + superclass = + DependentBaseClassTemplateName(descriptor_) + "<" + classname_ + ">"; } else { - initializer_with_arena = "_arena_ptr_(arena)"; + superclass = SuperClassName(descriptor_); } + string initializer_with_arena = superclass + "()"; + if (descriptor_->extension_range_count() > 0) { - initializer_with_arena = string("\n _extensions_(arena)") + - (!initializer_with_arena.empty() ? ", " : "") + initializer_with_arena; + initializer_with_arena += ",\n _extensions_(arena)"; + } + + if (UseUnknownFieldSet(descriptor_->file())) { + initializer_with_arena += ",\n _internal_metadata_(arena)"; } else { - initializer_with_arena = "\n " + initializer_with_arena; + initializer_with_arena += ",\n _arena_ptr_(arena)"; } // Initialize member variables with arena constructor. @@ -1804,16 +2079,21 @@ GenerateStructors(io::Printer* printer) { FieldName(descriptor_->field(i)) + string("_(arena)"); } } - initializer_with_arena = superclass + "()" + - (!initializer_with_arena.empty() ? "," : " ") + initializer_with_arena; + + if (IsAnyMessage(descriptor_)) { + initializer_with_arena += ",\n _any_metadata_(&type_url, &value_)"; + } string initializer_null; initializer_null = (UseUnknownFieldSet(descriptor_->file()) ? - ", _internal_metadata_(NULL) " : ", _arena_ptr_(NULL)"); + ", _internal_metadata_(NULL)" : ", _arena_ptr_(NULL)"); + if (IsAnyMessage(descriptor_)) { + initializer_null += ", _any_metadata_(&type_url_, &value_)"; + } printer->Print( "$classname$::$classname$()\n" - " : $superclass$() $initializer$ {\n" + " : $superclass$()$initializer$ {\n" " SharedCtor();\n" " // @@protoc_insertion_point(constructor:$full_name$)\n" "}\n", @@ -1894,10 +2174,14 @@ GenerateStructors(io::Printer* printer) { "full_name", descriptor_->full_name()); if (UseUnknownFieldSet(descriptor_->file())) { printer->Print( - ",\n _internal_metadata_(NULL) {\n"); + ",\n _internal_metadata_(NULL)"); } else if (!UseUnknownFieldSet(descriptor_->file())) { - printer->Print(",\n _arena_ptr_(NULL) {\n"); + printer->Print(",\n _arena_ptr_(NULL)"); } + if (IsAnyMessage(descriptor_)) { + printer->Print(",\n _any_metadata_(&type_url_, &value_)"); + } + printer->Print(" {\n"); printer->Print( " SharedCtor();\n" " MergeFrom(from);\n" @@ -2096,7 +2380,7 @@ GenerateClear(io::Printer* printer) { } else { if (HasFieldPresence(descriptor_->file())) { printer->Print( - "if (_has_bits_[$index$ / 32] & $mask$) {\n", + "if (_has_bits_[$index$ / 32] & $mask$u) {\n", "index", SimpleItoa(i / 8 * 8), "mask", SimpleItoa(mask)); printer->Indent(); @@ -2124,7 +2408,11 @@ GenerateClear(io::Printer* printer) { have_enclosing_if = true; } - field_generators_.get(field).GenerateClearingCode(printer); + if (use_dependent_base_ && IsFieldDependent(field)) { + printer->Print("clear_$name$();\n", "name", fieldname); + } else { + field_generators_.get(field).GenerateClearingCode(printer); + } if (have_enclosing_if) { printer->Outdent(); @@ -2147,7 +2435,11 @@ GenerateClear(io::Printer* printer) { const FieldDescriptor* field = descriptor_->field(i); if (field->is_repeated()) { - field_generators_.get(field).GenerateClearingCode(printer); + if (use_dependent_base_ && IsFieldDependent(field)) { + printer->Print("clear_$name$();\n", "name", FieldName(field)); + } else { + field_generators_.get(field).GenerateClearingCode(printer); + } } } @@ -2184,19 +2476,38 @@ void MessageGenerator:: GenerateOneofClear(io::Printer* printer) { // Generated function clears the active field and union case (e.g. foo_case_). for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { - printer->Print( - "void $classname$::clear_$oneofname$() {\n", - "classname", classname_, - "oneofname", descriptor_->oneof_decl(i)->name()); + map<string, string> oneof_vars; + oneof_vars["classname"] = classname_; + oneof_vars["oneofname"] = descriptor_->oneof_decl(i)->name(); + string message_class; + + if (use_dependent_base_) { + oneof_vars["tmpl"] = "template<class T>\n"; + oneof_vars["inline"] = "inline "; + oneof_vars["dependent_classname"] = + DependentBaseClassTemplateName(descriptor_) + "<T>"; + oneof_vars["this_message"] = "reinterpret_cast<T*>(this)->"; + message_class = "T::"; + } else { + oneof_vars["tmpl"] = ""; + oneof_vars["inline"] = ""; + oneof_vars["dependent_classname"] = classname_; + oneof_vars["this_message"] = ""; + } + + printer->Print(oneof_vars, + "$tmpl$" + "$inline$" + "void $dependent_classname$::clear_$oneofname$() {\n"); printer->Indent(); - printer->Print( - "switch($oneofname$_case()) {\n", - "oneofname", descriptor_->oneof_decl(i)->name()); + printer->Print(oneof_vars, + "switch($this_message$$oneofname$_case()) {\n"); printer->Indent(); for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); printer->Print( - "case k$field_name$: {\n", + "case $message_class$k$field_name$: {\n", + "message_class", message_class, "field_name", UnderscoresToCamelCase(field->name(), true)); printer->Indent(); // We clear only allocated objects in oneofs @@ -2213,16 +2524,20 @@ GenerateOneofClear(io::Printer* printer) { "}\n"); } printer->Print( - "case $cap_oneof_name$_NOT_SET: {\n" + "case $message_class$$cap_oneof_name$_NOT_SET: {\n" " break;\n" "}\n", + "message_class", message_class, "cap_oneof_name", ToUpper(descriptor_->oneof_decl(i)->name())); printer->Outdent(); printer->Print( "}\n" - "_oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n", + "$this_message$_oneof_case_[$oneof_index$] = " + "$message_class$$cap_oneof_name$_NOT_SET;\n", + "this_message", oneof_vars["this_message"], "oneof_index", SimpleItoa(i), + "message_class", message_class, "cap_oneof_name", ToUpper(descriptor_->oneof_decl(i)->name())); printer->Outdent(); @@ -2333,9 +2648,9 @@ GenerateMergeFrom(io::Printer* printer) { // system, as the GOOGLE_CHECK above ensured that we have the same descriptor // for each message. printer->Print( - "const $classname$* source =\n" - " ::google::protobuf::internal::dynamic_cast_if_available<const $classname$*>(\n" - " &from);\n" + "const $classname$* source = \n" + " ::google::protobuf::internal::DynamicCastToGenerated<const $classname$>(\n" + " &from);\n" "if (source == NULL) {\n" " ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n" "} else {\n" @@ -2585,8 +2900,24 @@ GenerateMergeFromCodedStream(io::Printer* printer) { printer->Indent(); + // Find repeated messages and groups now, to simplify what follows. + hash_set<int> fields_with_parse_loop; + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = ordered_fields[i]; + if (field->is_repeated() && + (field->type() == FieldDescriptor::TYPE_MESSAGE || + field->type() == FieldDescriptor::TYPE_GROUP)) { + fields_with_parse_loop.insert(i); + } + } + + // need_label is true if we generated "goto parse_$name$" while handling the + // previous field. + bool need_label = false; for (int i = 0; i < descriptor_->field_count(); i++) { const FieldDescriptor* field = ordered_fields[i]; + const bool loops = fields_with_parse_loop.count(i) > 0; + const bool next_field_loops = fields_with_parse_loop.count(i + 1) > 0; PrintFieldComment(printer, field); @@ -2600,9 +2931,16 @@ GenerateMergeFromCodedStream(io::Printer* printer) { printer->Print("if (tag == $commontag$) {\n", "commontag", SimpleItoa(WireFormat::MakeTag(field))); - if (i > 0 || (field->is_repeated() && !field->options().packed())) { + if (need_label || + (field->is_repeated() && !field->options().packed() && !loops)) { + printer->Print( + " parse_$name$:\n", + "name", field->name()); + } + if (loops) { printer->Print( - " parse_$name$:\n", + " DO_(input->IncrementRecursionDepth());\n" + " parse_loop_$name$:\n", "name", field->name()); } @@ -2644,26 +2982,53 @@ GenerateMergeFromCodedStream(io::Printer* printer) { // switch() is slow since it can't be predicted well. Insert some if()s // here that attempt to predict the next tag. - if (field->is_repeated() && !field->options().packed()) { - // Expect repeats of this field. + // For non-packed repeated fields, expect the same tag again. + if (loops) { + printer->Print( + "if (input->ExpectTag($tag$)) goto parse_loop_$name$;\n", + "tag", SimpleItoa(WireFormat::MakeTag(field)), + "name", field->name()); + } else if (field->is_repeated() && !field->options().packed()) { printer->Print( "if (input->ExpectTag($tag$)) goto parse_$name$;\n", "tag", SimpleItoa(WireFormat::MakeTag(field)), "name", field->name()); } - if (i + 1 < descriptor_->field_count()) { - // Expect the next field in order. - const FieldDescriptor* next_field = ordered_fields[i + 1]; - printer->Print( - "if (input->ExpectTag($next_tag$)) goto parse_$next_name$;\n", - "next_tag", SimpleItoa(WireFormat::MakeTag(next_field)), - "next_name", next_field->name()); - } else { - // Expect EOF. - // TODO(kenton): Expect group end-tag? + // Have we emitted "if (input->ExpectTag($next_tag$)) ..." yet? + bool emitted_goto_next_tag = false; + + // For repeated messages/groups, we need to decrement recursion depth, + // unless the next tag is also for a repeated message/group. + if (loops) { + if (next_field_loops) { + const FieldDescriptor* next_field = ordered_fields[i + 1]; + printer->Print( + "if (input->ExpectTag($next_tag$)) goto parse_loop_$next_name$;\n", + "next_tag", SimpleItoa(WireFormat::MakeTag(next_field)), + "next_name", next_field->name()); + emitted_goto_next_tag = true; + } printer->Print( - "if (input->ExpectAtEnd()) goto success;\n"); + "input->UnsafeDecrementRecursionDepth();\n"); + } + + // If there are more fields, expect the next one. + need_label = false; + if (!emitted_goto_next_tag) { + if (i + 1 == descriptor_->field_count()) { + // Expect EOF. + // TODO(kenton): Expect group end-tag? + printer->Print( + "if (input->ExpectAtEnd()) goto success;\n"); + } else { + const FieldDescriptor* next_field = ordered_fields[i + 1]; + printer->Print( + "if (input->ExpectTag($next_tag$)) goto parse_$next_name$;\n", + "next_tag", SimpleItoa(WireFormat::MakeTag(next_field)), + "next_name", next_field->name()); + need_label = true; + } } printer->Print( @@ -2999,9 +3364,7 @@ static string ConditionalToCheckBitmasks(const vector<uint32>& masks) { vector<string> parts; for (int i = 0; i < masks.size(); i++) { if (masks[i] == 0) continue; - char buffer[kFastToBufferSize]; - FastHex32ToBuffer(masks[i], buffer); - string m = StrCat("0x", buffer); + string m = StrCat("0x", strings::Hex(masks[i], strings::Hex::ZERO_PAD_8)); // Each xor evaluates to 0 if the expected bits are present. parts.push_back(StrCat("((_has_bits_[", i, "] & ", m, ") ^ ", m, ")")); } @@ -3293,11 +3656,10 @@ GenerateIsInitialized(io::Printer* printer) { } if (mask != 0) { - char buffer[kFastToBufferSize]; printer->Print( "if ((_has_bits_[$i$] & 0x$mask$) != 0x$mask$) return false;\n", "i", SimpleItoa(i), - "mask", FastHex32ToBuffer(mask, buffer)); + "mask", StrCat(strings::Hex(mask, strings::Hex::ZERO_PAD_8))); } } } diff --git a/src/google/protobuf/compiler/cpp/cpp_message.h b/src/google/protobuf/compiler/cpp/cpp_message.h index ea96581d..23dad10c 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.h +++ b/src/google/protobuf/compiler/cpp/cpp_message.h @@ -67,7 +67,8 @@ class MessageGenerator { // Header stuff. // Generate foward declarations for this class and all its nested types. - void GenerateForwardDeclaration(io::Printer* printer); + void GenerateMessageForwardDeclaration(io::Printer* printer); + void GenerateEnumForwardDeclaration(io::Printer* printer); // Generate definitions of all nested enums (must come before class // definitions because those classes use the enums definitions). @@ -84,6 +85,9 @@ class MessageGenerator { // file). void GenerateInlineMethods(io::Printer* printer, bool is_inline); + // Dependent methods are always inline. + void GenerateDependentInlineMethods(io::Printer* printer); + // Source file stuff. // Generate code which declares all the global descriptor pointers which @@ -115,7 +119,10 @@ class MessageGenerator { private: // Generate declarations and definitions of accessors for fields. + void GenerateDependentBaseClassDefinition(io::Printer* printer); + void GenerateDependentFieldAccessorDeclarations(io::Printer* printer); void GenerateFieldAccessorDeclarations(io::Printer* printer); + void GenerateDependentFieldAccessorDefinitions(io::Printer* printer); void GenerateFieldAccessorDefinitions(io::Printer* printer, bool is_inline); // Generate the field offsets array. @@ -158,6 +165,21 @@ class MessageGenerator { bool unbounded); + // Generates has_foo() functions and variables for singular field has-bits. + void GenerateSingularFieldHasBits(const FieldDescriptor* field, + map<string, string> vars, + io::Printer* printer); + // Generates has_foo() functions and variables for oneof field has-bits. + void GenerateOneofHasBits(io::Printer* printer, bool is_inline); + // Generates has_foo_bar() functions for oneof members. + void GenerateOneofMemberHasBits(const FieldDescriptor* field, + const map<string, string>& vars, + io::Printer* printer); + // Generates the clear_foo() method for a field. + void GenerateFieldClear(const FieldDescriptor* field, + const map<string, string>& vars, + io::Printer* printer); + const Descriptor* descriptor_; string classname_; Options options_; @@ -168,6 +190,7 @@ class MessageGenerator { google::protobuf::scoped_array<google::protobuf::scoped_ptr<ExtensionGenerator> > extension_generators_; int num_required_fields_; bool uses_string_; + bool use_dependent_base_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator); }; diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/src/google/protobuf/compiler/cpp/cpp_message_field.cc index 467b6bf6..ba318d10 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message_field.cc @@ -72,7 +72,8 @@ void SetMessageVariables(const FieldDescriptor* descriptor, MessageFieldGenerator:: MessageFieldGenerator(const FieldDescriptor* descriptor, const Options& options) - : descriptor_(descriptor) { + : descriptor_(descriptor), + dependent_field_(options.proto_h && IsFieldDependent(descriptor)) { SetMessageVariables(descriptor, &variables_, options); } @@ -84,6 +85,10 @@ GeneratePrivateMembers(io::Printer* printer) const { } void MessageFieldGenerator:: +GenerateDependentAccessorDeclarations(io::Printer* printer) const { +} + +void MessageFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { if (SupportsArenas(descriptor_)) { printer->Print(variables_, @@ -144,6 +149,8 @@ void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions( " return temp;\n" "}\n"); if (SupportsArenas(descriptor_->message_type())) { + // NOTE: the same logic is mirrored in weak_message_field.cc. Any + // arena-related semantics changes should be made in both places. printer->Print(variables_, "void $classname$::_slow_set_allocated_$name$(\n" " ::google::protobuf::Arena* message_arena, $type$** $name$) {\n" @@ -181,6 +188,10 @@ void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions( } void MessageFieldGenerator:: +GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const { +} + +void MessageFieldGenerator:: GenerateInlineAccessorDefinitions(io::Printer* printer, bool is_inline) const { map<string, string> variables(variables_); @@ -294,7 +305,7 @@ GenerateClearingCode(io::Printer* printer) const { // If we don't have has-bits, message presence is indicated only by ptr != // NULL. Thus on clear, we need to delete the object. printer->Print(variables_, - "if ($name$_ != NULL) delete $name$_;\n" + "if (GetArenaNoVirtual() == NULL && $name$_ != NULL) delete $name$_;\n" "$name$_ = NULL;\n"); } else { printer->Print(variables_, @@ -366,6 +377,10 @@ MessageOneofFieldGenerator(const FieldDescriptor* descriptor, MessageOneofFieldGenerator::~MessageOneofFieldGenerator() {} void MessageOneofFieldGenerator:: +GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const { +} + +void MessageOneofFieldGenerator:: GenerateInlineAccessorDefinitions(io::Printer* printer, bool is_inline) const { map<string, string> variables(variables_); @@ -560,6 +575,10 @@ GeneratePrivateMembers(io::Printer* printer) const { } void RepeatedMessageFieldGenerator:: +GenerateDependentAccessorDeclarations(io::Printer* printer) const { +} + +void RepeatedMessageFieldGenerator:: GenerateAccessorDeclarations(io::Printer* printer) const { printer->Print(variables_, "const $type$& $name$(int index) const$deprecation$;\n" @@ -573,6 +592,10 @@ GenerateAccessorDeclarations(io::Printer* printer) const { } void RepeatedMessageFieldGenerator:: +GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const { +} + +void RepeatedMessageFieldGenerator:: GenerateInlineAccessorDefinitions(io::Printer* printer, bool is_inline) const { map<string, string> variables(variables_); @@ -627,11 +650,13 @@ void RepeatedMessageFieldGenerator:: GenerateMergeFromCodedStream(io::Printer* printer) const { if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) { printer->Print(variables_, - "DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n" + "DO_(::google::protobuf::internal::WireFormatLite::" + "ReadMessageNoVirtualNoRecursionDepth(\n" " input, add_$name$()));\n"); } else { printer->Print(variables_, - "DO_(::google::protobuf::internal::WireFormatLite::ReadGroupNoVirtual(\n" + "DO_(::google::protobuf::internal::WireFormatLite::" + "ReadGroupNoVirtualNoRecursionDepth(\n" " $number$, input, add_$name$()));\n"); } } diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.h b/src/google/protobuf/compiler/cpp/cpp_message_field.h index c1704fc1..9ddf9643 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_message_field.h @@ -52,7 +52,9 @@ class MessageFieldGenerator : public FieldGenerator { // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const; + void GenerateDependentAccessorDeclarations(io::Printer* printer) const; void GenerateAccessorDeclarations(io::Printer* printer) const; + void GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const; void GenerateInlineAccessorDefinitions(io::Printer* printer, bool is_inline) const; void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const; @@ -67,6 +69,7 @@ class MessageFieldGenerator : public FieldGenerator { protected: const FieldDescriptor* descriptor_; + const bool dependent_field_; map<string, string> variables_; private: @@ -80,6 +83,7 @@ class MessageOneofFieldGenerator : public MessageFieldGenerator { ~MessageOneofFieldGenerator(); // implements FieldGenerator --------------------------------------- + void GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const; void GenerateInlineAccessorDefinitions(io::Printer* printer, bool is_inline) const; void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const {} @@ -99,7 +103,9 @@ class RepeatedMessageFieldGenerator : public FieldGenerator { // implements FieldGenerator --------------------------------------- void GeneratePrivateMembers(io::Printer* printer) const; + void GenerateDependentAccessorDeclarations(io::Printer* printer) const; void GenerateAccessorDeclarations(io::Printer* printer) const; + void GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const; void GenerateInlineAccessorDefinitions(io::Printer* printer, bool is_inline) const; void GenerateClearingCode(io::Printer* printer) const; diff --git a/src/google/protobuf/compiler/cpp/cpp_options.h b/src/google/protobuf/compiler/cpp/cpp_options.h index 0c99cff1..4463f200 100644 --- a/src/google/protobuf/compiler/cpp/cpp_options.h +++ b/src/google/protobuf/compiler/cpp/cpp_options.h @@ -41,12 +41,13 @@ namespace protobuf { namespace compiler { namespace cpp { -// Generator options: +// Generator options (see generator.cc for a description of each): struct Options { - Options() : safe_boundary_check(false) { + Options() : safe_boundary_check(false), proto_h(false) { } string dllexport_decl; bool safe_boundary_check; + bool proto_h; }; } // namespace cpp diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc index 329eae32..9f929d37 100644 --- a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc @@ -262,7 +262,7 @@ RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, : descriptor_(descriptor) { SetPrimitiveVariables(descriptor, &variables_, options); - if (descriptor->options().packed()) { + if (descriptor->is_packed()) { variables_["packed_reader"] = "ReadPackedPrimitive"; variables_["repeated_reader"] = "ReadRepeatedPrimitiveNoInline"; } else { @@ -277,7 +277,7 @@ void RepeatedPrimitiveFieldGenerator:: GeneratePrivateMembers(io::Printer* printer) const { printer->Print(variables_, "::google::protobuf::RepeatedField< $type$ > $name$_;\n"); - if (descriptor_->options().packed() && HasGeneratedMethods(descriptor_->file())) { + if (descriptor_->is_packed() && HasGeneratedMethods(descriptor_->file())) { printer->Print(variables_, "mutable int _$name$_cached_byte_size_;\n"); } @@ -364,7 +364,7 @@ GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const { void RepeatedPrimitiveFieldGenerator:: GenerateSerializeWithCachedSizes(io::Printer* printer) const { - if (descriptor_->options().packed()) { + if (descriptor_->is_packed()) { // Write the tag and the size. printer->Print(variables_, "if (this->$name$_size() > 0) {\n" @@ -377,7 +377,7 @@ GenerateSerializeWithCachedSizes(io::Printer* printer) const { } printer->Print(variables_, "for (int i = 0; i < this->$name$_size(); i++) {\n"); - if (descriptor_->options().packed()) { + if (descriptor_->is_packed()) { printer->Print(variables_, " ::google::protobuf::internal::WireFormatLite::Write$declared_type$NoTag(\n" " this->$name$(i), output);\n"); @@ -391,7 +391,7 @@ GenerateSerializeWithCachedSizes(io::Printer* printer) const { void RepeatedPrimitiveFieldGenerator:: GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { - if (descriptor_->options().packed()) { + if (descriptor_->is_packed()) { // Write the tag and the size. printer->Print(variables_, "if (this->$name$_size() > 0) {\n" @@ -405,7 +405,7 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { } printer->Print(variables_, "for (int i = 0; i < this->$name$_size(); i++) {\n"); - if (descriptor_->options().packed()) { + if (descriptor_->is_packed()) { printer->Print(variables_, " target = ::google::protobuf::internal::WireFormatLite::\n" " Write$declared_type$NoTagToArray(this->$name$(i), target);\n"); @@ -435,7 +435,7 @@ GenerateByteSize(io::Printer* printer) const { "data_size = $fixed_size$ * this->$name$_size();\n"); } - if (descriptor_->options().packed()) { + if (descriptor_->is_packed()) { printer->Print(variables_, "if (data_size > 0) {\n" " total_size += $tag_size$ +\n" diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc index 1a1bcd3d..1a3896a1 100644 --- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc @@ -226,7 +226,6 @@ GenerateInlineAccessorDefinitions(io::Printer* printer, " } else {\n" " $clear_hasbit$\n" " }\n" - " $set_hasbit$\n" " $name$_.UnsafeArenaSetAllocated($default_variable$,\n" " $name$, GetArenaNoVirtual());\n" " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" diff --git a/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto b/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto index 9f63155b..4e25b2ea 100644 --- a/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto +++ b/src/google/protobuf/compiler/cpp/cpp_test_bad_identifiers.proto @@ -131,23 +131,23 @@ message TestConflictingSymbolNamesExtension { // NO_PROTO3 } // NO_PROTO3 } // NO_PROTO3 -message TestConflictingEnumNames { - enum NestedConflictingEnum { - and = 1; - class = 2; - int = 3; - typedef = 4; - XOR = 5; - } - - optional NestedConflictingEnum conflicting_enum = 1; -} - -enum ConflictingEnum { - NOT_EQ = 1; - volatile = 2; - return = 3; -} +message TestConflictingEnumNames { // NO_PROTO3 + enum NestedConflictingEnum { // 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 NestedConflictingEnum conflicting_enum = 1; // NO_PROTO3 +} // NO_PROTO3 + +enum ConflictingEnum { // NO_PROTO3 + NOT_EQ = 1; // NO_PROTO3 + volatile = 2; // NO_PROTO3 + return = 3; // NO_PROTO3 +} // NO_PROTO3 message DummyMessage {} diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_unittest.cc index cc758cf5..b11fb21a 100644 --- a/src/google/protobuf/compiler/cpp/cpp_unittest.cc +++ b/src/google/protobuf/compiler/cpp/cpp_unittest.cc @@ -941,6 +941,22 @@ TEST(GeneratedMessageTest, ExtensionConstantValues) { EXPECT_EQ(unittest::kRepeatedNestedEnumExtensionFieldNumber, 51); } +TEST(GeneratedMessageTest, ParseFromTruncated) { + const string long_string = string(128, 'q'); + FileDescriptorProto p; + p.add_extension()->set_name(long_string); + const 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(GeneratedEnumTest, EnumValuesAsSwitchCases) { @@ -1392,6 +1408,12 @@ class OneofTest : public testing::Test { 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; @@ -1404,6 +1426,9 @@ class OneofTest : public testing::Test { 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; } diff --git a/src/google/protobuf/compiler/cpp/test_large_enum_value.proto b/src/google/protobuf/compiler/cpp/test_large_enum_value.proto new file mode 100644 index 00000000..cb6ca1b1 --- /dev/null +++ b/src/google/protobuf/compiler/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/src/google/protobuf/compiler/csharp/csharp_enum.cc b/src/google/protobuf/compiler/csharp/csharp_enum.cc new file mode 100644 index 00000000..27643e61 --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_enum.cc @@ -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. + +#include <sstream> + +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/compiler/plugin.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/stubs/strutil.h> + +#include <google/protobuf/compiler/csharp/csharp_enum.h> +#include <google/protobuf/compiler/csharp/csharp_helpers.h> +#include <google/protobuf/compiler/csharp/csharp_writer.h> + +using google::protobuf::internal::scoped_ptr; + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor) : + SourceGeneratorBase(descriptor->file()), + descriptor_(descriptor) { +} + +EnumGenerator::~EnumGenerator() { +} + +void EnumGenerator::Generate(Writer* writer) { + WriteGeneratedCodeAttributes(writer); + writer->WriteLine("$0$ enum $1$ {", + class_access_level(), + descriptor_->name()); + writer->Indent(); + for (int i = 0; i < descriptor_->value_count(); i++) { + writer->WriteLine("$0$ = $1$,", + descriptor_->value(i)->name(), + SimpleItoa(descriptor_->value(i)->number())); + } + writer->Outdent(); + writer->WriteLine("}"); + writer->WriteLine(); +} + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/csharp/csharp_enum.h b/src/google/protobuf/compiler/csharp/csharp_enum.h new file mode 100644 index 00000000..eaa7a9c5 --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_enum.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. + +#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_H__ +#define GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_H__ + +#include <string> + +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/compiler/csharp/csharp_source_generator_base.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +class Writer; + +class EnumGenerator : public SourceGeneratorBase { + public: + EnumGenerator(const EnumDescriptor* descriptor); + ~EnumGenerator(); + + void Generate(Writer* writer); + + private: + const EnumDescriptor* descriptor_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator); +}; + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_H__ + diff --git a/src/google/protobuf/compiler/csharp/csharp_enum_field.cc b/src/google/protobuf/compiler/csharp/csharp_enum_field.cc new file mode 100644 index 00000000..28f5a05c --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_enum_field.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 <sstream> + +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/compiler/plugin.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/io/zero_copy_stream.h> + +#include <google/protobuf/compiler/csharp/csharp_helpers.h> +#include <google/protobuf/compiler/csharp/csharp_enum_field.h> +#include <google/protobuf/compiler/csharp/csharp_writer.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +EnumFieldGenerator::EnumFieldGenerator(const FieldDescriptor* descriptor, + int fieldOrdinal) + : PrimitiveFieldGenerator(descriptor, fieldOrdinal) { +} + +EnumFieldGenerator::~EnumFieldGenerator() { +} + +void EnumFieldGenerator::GenerateParsingCode(Writer* writer) { + writer->WriteLine("object unknown;"); + writer->WriteLine("if(input.ReadEnum(ref result.$0$_, out unknown)) {", name()); + if (SupportFieldPresence(descriptor_->file())) { + writer->WriteLine(" result.has$0$ = true;", property_name()); + } + writer->WriteLine("} else if(unknown is int) {"); + if (!use_lite_runtime()) { + writer->WriteLine(" if (unknownFields == null) {"); // First unknown field - create builder now + writer->WriteLine( + " unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);"); + writer->WriteLine(" }"); + writer->WriteLine( + " unknownFields.MergeVarintField($0$, (ulong)(int)unknown);", + number()); + } + writer->WriteLine("}"); +} + +void EnumFieldGenerator::GenerateSerializationCode(Writer* writer) { + writer->WriteLine("if ($0$) {", has_property_check); + writer->WriteLine( + " output.WriteEnum($0$, field_names[$2$], (int) $1$, $1$);", number(), + property_name(), field_ordinal()); + writer->WriteLine("}"); +} + +void EnumFieldGenerator::GenerateSerializedSizeCode(Writer* writer) { + writer->WriteLine("if ($0$) {", has_property_check); + writer->WriteLine( + " size += pb::CodedOutputStream.ComputeEnumSize($0$, (int) $1$);", + number(), property_name()); + writer->WriteLine("}"); +} + +EnumOneofFieldGenerator::EnumOneofFieldGenerator(const FieldDescriptor* descriptor, + int fieldOrdinal) + : PrimitiveOneofFieldGenerator(descriptor, fieldOrdinal) { +} + +EnumOneofFieldGenerator::~EnumOneofFieldGenerator() { +} + +void EnumOneofFieldGenerator::GenerateParsingCode(Writer* writer) { + writer->WriteLine("object unknown;"); + writer->WriteLine("$0$ enumValue = $1$;", type_name(), default_value()); + writer->WriteLine("if(input.ReadEnum(ref enumValue, out unknown)) {", + name()); + writer->WriteLine(" result.$0$_ = enumValue;", oneof_name()); + writer->WriteLine(" result.$0$Case_ = $1$OneofCase.$2$;", + oneof_name(), oneof_property_name(), property_name()); + writer->WriteLine("} else if(unknown is int) {"); + if (!use_lite_runtime()) { + writer->WriteLine(" if (unknownFields == null) {"); // First unknown field - create builder now + writer->WriteLine( + " unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);"); + writer->WriteLine(" }"); + writer->WriteLine( + " unknownFields.MergeVarintField($0$, (ulong)(int)unknown);", + number()); + } + writer->WriteLine("}"); +} + +void EnumOneofFieldGenerator::GenerateSerializationCode(Writer* writer) { + writer->WriteLine("if ($0$) {", has_property_check); + writer->WriteLine( + " output.WriteEnum($0$, field_names[$2$], (int) $1$, $1$);", number(), + property_name(), field_ordinal()); + writer->WriteLine("}"); +} + +void EnumOneofFieldGenerator::GenerateSerializedSizeCode(Writer* writer) { + writer->WriteLine("if ($0$) {", has_property_check); + writer->WriteLine( + " size += pb::CodedOutputStream.ComputeEnumSize($0$, (int) $1$);", + number(), property_name()); + writer->WriteLine("}"); +} + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/csharp/csharp_enum_field.h b/src/google/protobuf/compiler/csharp/csharp_enum_field.h new file mode 100644 index 00000000..c6b7b848 --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_enum_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_CSHARP_ENUM_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_FIELD_H__ + +#include <string> + +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/compiler/csharp/csharp_primitive_field.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +class Writer; + +class EnumFieldGenerator : public PrimitiveFieldGenerator { + public: + EnumFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); + ~EnumFieldGenerator(); + + virtual void GenerateParsingCode(Writer* writer); + virtual void GenerateSerializationCode(Writer* writer); + virtual void GenerateSerializedSizeCode(Writer* writer); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator); +}; + +class EnumOneofFieldGenerator : public PrimitiveOneofFieldGenerator { + public: + EnumOneofFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); + ~EnumOneofFieldGenerator(); + + virtual void GenerateParsingCode(Writer* writer); + virtual void GenerateSerializationCode(Writer* writer); + virtual void GenerateSerializedSizeCode(Writer* writer); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumOneofFieldGenerator); +}; + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_FIELD_H__ + diff --git a/src/google/protobuf/compiler/csharp/csharp_extension.cc b/src/google/protobuf/compiler/csharp/csharp_extension.cc new file mode 100644 index 00000000..2bac320d --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_extension.cc @@ -0,0 +1,166 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (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 <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/compiler/plugin.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/io/zero_copy_stream.h> + +#include <google/protobuf/compiler/csharp/csharp_extension.h> +#include <google/protobuf/compiler/csharp/csharp_helpers.h> +#include <google/protobuf/compiler/csharp/csharp_writer.h> +#include <google/protobuf/compiler/csharp/csharp_field_base.h> + +using google::protobuf::internal::scoped_ptr; + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor) + : FieldGeneratorBase(descriptor, 0) { + if (descriptor_->extension_scope()) { + scope_ = GetClassName(descriptor_->extension_scope()); + } else { + scope_ = GetFullUmbrellaClassName(descriptor_->file()); + } + extends_ = GetClassName(descriptor_->containing_type()); +} + +ExtensionGenerator::~ExtensionGenerator() { +} + +void ExtensionGenerator::Generate(Writer* writer) { + writer->WriteLine("public const int $0$ = $1$;", + GetFieldConstantName(descriptor_), + SimpleItoa(descriptor_->number())); + + if (use_lite_runtime()) { + // TODO(jtattermusch): include the following check + //if (Descriptor.MappedType == MappedType.Message && Descriptor.MessageType.Options.MessageSetWireFormat) + //{ + // throw new ArgumentException( + // "option message_set_wire_format = true; is not supported in Lite runtime extensions."); + //} + + writer->Write("$0$ ", class_access_level()); + writer->WriteLine( + "static pb::$3$<$0$, $1$> $2$;", + extends_, + type_name(), + property_name(), + descriptor_->is_repeated() ? + "GeneratedRepeatExtensionLite" : "GeneratedExtensionLite"); + } else if (descriptor_->is_repeated()) { + writer->WriteLine( + "$0$ static pb::GeneratedExtensionBase<scg::IList<$1$>> $2$;", + class_access_level(), type_name(), property_name()); + } else { + writer->WriteLine("$0$ static pb::GeneratedExtensionBase<$1$> $2$;", + class_access_level(), type_name(), property_name()); + } +} + +void ExtensionGenerator::GenerateStaticVariableInitializers(Writer* writer) { + if (use_lite_runtime()) { + writer->WriteLine("$0$.$1$ = ", scope_, property_name()); + writer->Indent(); + writer->WriteLine( + "new pb::$0$<$1$, $2$>(", + descriptor_->is_repeated() ? + "GeneratedRepeatExtensionLite" : "GeneratedExtensionLite", + extends_, type_name()); + writer->Indent(); + writer->WriteLine("\"$0$\",", descriptor_->full_name()); + writer->WriteLine("$0$.DefaultInstance,", extends_); + if (!descriptor_->is_repeated()) { + std::string default_val; + if (descriptor_->has_default_value()) { + default_val = default_value(); + } else { + default_val = is_nullable_type() ? "null" : ("default(" + type_name() + ")"); + } + writer->WriteLine("$0$,", default_val); + } + writer->WriteLine( + "$0$,", + (GetCSharpType(descriptor_->type()) == CSHARPTYPE_MESSAGE) ? + type_name() + ".DefaultInstance" : "null"); + writer->WriteLine( + "$0$,", + (GetCSharpType(descriptor_->type()) == CSHARPTYPE_ENUM) ? + "new EnumLiteMap<" + type_name() + ">()" : "null"); + writer->WriteLine("$0$.$1$FieldNumber,", scope_, + GetPropertyName(descriptor_)); + writer->Write("pbd::FieldType.$0$", capitalized_type_name()); + if (descriptor_->is_repeated()) { + writer->WriteLine(","); + writer->Write(descriptor_->is_packed() ? "true" : "false"); + } + writer->Outdent(); + writer->WriteLine(");"); + writer->Outdent(); + } + else if (descriptor_->is_repeated()) + { + writer->WriteLine( + "$0$.$1$ = pb::GeneratedRepeatExtension<$2$>.CreateInstance($0$.Descriptor.Extensions[$3$]);", + scope_, property_name(), type_name(), SimpleItoa(descriptor_->index())); + } + else + { + writer->WriteLine( + "$0$.$1$ = pb::GeneratedSingleExtension<$2$>.CreateInstance($0$.Descriptor.Extensions[$3$]);", + scope_, property_name(), type_name(), SimpleItoa(descriptor_->index())); + } +} + +void ExtensionGenerator::GenerateExtensionRegistrationCode(Writer* writer) { + writer->WriteLine("registry.Add($0$.$1$);", scope_, property_name()); +} + +void ExtensionGenerator::WriteHash(Writer* writer) { +} + +void ExtensionGenerator::WriteEquals(Writer* writer) { +} + +void ExtensionGenerator::WriteToString(Writer* writer) { +} + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/csharp/csharp_extension.h b/src/google/protobuf/compiler/csharp/csharp_extension.h new file mode 100644 index 00000000..203f6e5e --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_extension.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_CSHARP_EXTENSION_H__ +#define GOOGLE_PROTOBUF_COMPILER_CSHARP_EXTENSION_H__ + +#include <string> + +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/compiler/csharp/csharp_field_base.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +class Writer; + +class ExtensionGenerator : public FieldGeneratorBase { + public: + ExtensionGenerator(const FieldDescriptor* descriptor); + ~ExtensionGenerator(); + + void GenerateStaticVariableInitializers(Writer* writer); + void GenerateExtensionRegistrationCode(Writer* writer); + void Generate(Writer* writer); + + virtual void WriteHash(Writer* writer); + virtual void WriteEquals(Writer* writer); + virtual void WriteToString(Writer* writer); + + virtual void GenerateMembers(Writer* writer) {}; + virtual void GenerateBuilderMembers(Writer* writer) {}; + virtual void GenerateMergingCode(Writer* writer) {}; + virtual void GenerateBuildingCode(Writer* writer) {}; + virtual void GenerateParsingCode(Writer* writer) {}; + virtual void GenerateSerializationCode(Writer* writer) {}; + virtual void GenerateSerializedSizeCode(Writer* writer) {}; + + private: + std::string scope_; + std::string extends_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator); +}; + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_EXTENSION_H__ + diff --git a/src/google/protobuf/compiler/csharp/csharp_field_base.cc b/src/google/protobuf/compiler/csharp/csharp_field_base.cc new file mode 100644 index 00000000..dfc803e6 --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_field_base.cc @@ -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. + +#include <limits> +#include <sstream> + +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/compiler/plugin.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/stubs/strutil.h> + +#include <google/protobuf/compiler/csharp/csharp_field_base.h> +#include <google/protobuf/compiler/csharp/csharp_helpers.h> +#include <google/protobuf/compiler/csharp/csharp_writer.h> + +using google::protobuf::internal::scoped_ptr; + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +FieldGeneratorBase::FieldGeneratorBase(const FieldDescriptor* descriptor, + int fieldOrdinal) + : SourceGeneratorBase(descriptor->file()), + descriptor_(descriptor), + fieldOrdinal_(fieldOrdinal) { +} + +FieldGeneratorBase::~FieldGeneratorBase() { +} + +void FieldGeneratorBase::AddDeprecatedFlag(Writer* writer) { + if (descriptor_->options().deprecated()) + { + writer->WriteLine("[global::System.ObsoleteAttribute()]"); + } +} + +void FieldGeneratorBase::AddNullCheck(Writer* writer) { + AddNullCheck(writer, "value"); +} + +void FieldGeneratorBase::AddNullCheck(Writer* writer, const std::string& name) { + if (is_nullable_type()) { + writer->WriteLine(" pb::ThrowHelper.ThrowIfNull($0$, \"$0$\");", name); + } +} + +void FieldGeneratorBase::AddPublicMemberAttributes(Writer* writer) { + AddDeprecatedFlag(writer); +} + +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() { + switch (descriptor_->type()) { + case FieldDescriptor::TYPE_ENUM: + return GetClassName(descriptor_->enum_type()); + case FieldDescriptor::TYPE_MESSAGE: + case FieldDescriptor::TYPE_GROUP: + 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 FieldGeneratorBase::is_nullable_type() { + 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; + } +} + +inline bool IsNaN(double value) { + // NaN is never equal to anything, even itself. + return value != value; +} + +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() { + if (!descriptor_->has_default_value()) { + return "\"\""; + } + if (AllPrintableAscii(descriptor_->default_value_string())) { + // All chars are ASCII and printable. In this case we only + // need to escape quotes and backslashes. + std::string temp = descriptor_->default_value_string(); + temp = StringReplace(temp, "\\", "\\\\", true); + temp = StringReplace(temp, "'", "\\'", true); + temp = StringReplace(temp, "\"", "\\\"", true); + return "\"" + temp + "\""; + } + if (use_lite_runtime()) { + return "pb::ByteString.FromBase64(\"" + + StringToBase64(descriptor_->default_value_string()) + + "\").ToStringUtf8()"; + } + return "(string) " + GetClassName(descriptor_->containing_type()) + + ".Descriptor.Fields[" + SimpleItoa(descriptor_->index()) + + "].DefaultValue"; +} + +std::string FieldGeneratorBase::GetBytesDefaultValueInternal() { + if (!descriptor_->has_default_value()) { + return "pb::ByteString.Empty"; + } + if (use_lite_runtime()) { + return "pb::ByteString.FromBase64(\"" + StringToBase64(descriptor_->default_value_string()) + "\")"; + } + return "(pb::ByteString) "+ GetClassName(descriptor_->containing_type()) + + ".Descriptor.Fields[" + SimpleItoa(descriptor_->index()) + "].DefaultValue"; +} + +std::string FieldGeneratorBase::default_value() { + switch (descriptor_->type()) { + case FieldDescriptor::TYPE_ENUM: + return type_name() + "." + descriptor_->default_value_enum()->name(); + case FieldDescriptor::TYPE_MESSAGE: + case FieldDescriptor::TYPE_GROUP: + return type_name() + ".DefaultInstance"; + case FieldDescriptor::TYPE_DOUBLE: { + double value = descriptor_->default_value_double(); + if (value == numeric_limits<double>::infinity()) { + return "double.PositiveInfinity"; + } else if (value == -numeric_limits<double>::infinity()) { + return "double.NegativeInfinity"; + } else if (IsNaN(value)) { + return "double.NaN"; + } + return SimpleDtoa(value) + "D"; + } + case FieldDescriptor::TYPE_FLOAT: { + float value = descriptor_->default_value_float(); + if (value == numeric_limits<float>::infinity()) { + return "float.PositiveInfinity"; + } else if (value == -numeric_limits<float>::infinity()) { + return "float.NegativeInfinity"; + } else if (IsNaN(value)) { + return "float.NaN"; + } + return SimpleFtoa(value) + "F"; + } + case FieldDescriptor::TYPE_INT64: + return SimpleItoa(descriptor_->default_value_int64()) + "L"; + case FieldDescriptor::TYPE_UINT64: + return SimpleItoa(descriptor_->default_value_uint64()) + "UL"; + case FieldDescriptor::TYPE_INT32: + return SimpleItoa(descriptor_->default_value_int32()); + case FieldDescriptor::TYPE_FIXED64: + return SimpleItoa(descriptor_->default_value_uint64()) + "UL"; + case FieldDescriptor::TYPE_FIXED32: + return SimpleItoa(descriptor_->default_value_uint32()); + case FieldDescriptor::TYPE_BOOL: + if (descriptor_->default_value_bool()) { + return "true"; + } else { + return "false"; + } + case FieldDescriptor::TYPE_STRING: + return GetStringDefaultValueInternal(); + case FieldDescriptor::TYPE_BYTES: + return GetBytesDefaultValueInternal(); + case FieldDescriptor::TYPE_UINT32: + return SimpleItoa(descriptor_->default_value_uint32()); + case FieldDescriptor::TYPE_SFIXED32: + return SimpleItoa(descriptor_->default_value_int32()); + case FieldDescriptor::TYPE_SFIXED64: + return SimpleItoa(descriptor_->default_value_int64()) + "L"; + case FieldDescriptor::TYPE_SINT32: + return SimpleItoa(descriptor_->default_value_int32()); + case FieldDescriptor::TYPE_SINT64: + return SimpleItoa(descriptor_->default_value_int64()) + "L"; + default: + GOOGLE_LOG(FATAL)<< "Unknown field type."; + return ""; + } +} + +std::string FieldGeneratorBase::number() { + return SimpleItoa(descriptor_->number()); +} + +std::string FieldGeneratorBase::message_or_group() { + return + (descriptor_->type() == FieldDescriptor::TYPE_GROUP) ? "Group" : "Message"; +} + +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 ""; + } +} + +std::string FieldGeneratorBase::field_ordinal() { + return SimpleItoa(fieldOrdinal_); +} + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/csharp/csharp_field_base.h b/src/google/protobuf/compiler/csharp/csharp_field_base.h new file mode 100644 index 00000000..312da12b --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_field_base.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. + +#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_FIELD_BASE_H__ +#define GOOGLE_PROTOBUF_COMPILER_CSHARP_FIELD_BASE_H__ + +#include <string> +#include <google/protobuf/stubs/strutil.h> + +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/compiler/csharp/csharp_source_generator_base.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +class Writer; + +class FieldGeneratorBase : public SourceGeneratorBase { + public: + FieldGeneratorBase(const FieldDescriptor* descriptor, int fieldOrdinal); + ~FieldGeneratorBase(); + + virtual void GenerateMembers(Writer* writer) = 0; + virtual void GenerateBuilderMembers(Writer* writer) = 0; + virtual void GenerateMergingCode(Writer* writer) = 0; + virtual void GenerateBuildingCode(Writer* writer) = 0; + virtual void GenerateParsingCode(Writer* writer) = 0; + virtual void GenerateSerializationCode(Writer* writer) = 0; + virtual void GenerateSerializedSizeCode(Writer* writer) = 0; + + virtual void WriteHash(Writer* writer) = 0; + virtual void WriteEquals(Writer* writer) = 0; + virtual void WriteToString(Writer* writer) = 0; + + protected: + const FieldDescriptor* descriptor_; + const int fieldOrdinal_; + + void AddDeprecatedFlag(Writer* writer); + void AddNullCheck(Writer* writer); + void AddNullCheck(Writer* writer, const std::string& name); + + void AddPublicMemberAttributes(Writer* writer); + + std::string oneof_property_name(); + std::string oneof_name(); + std::string property_name(); + std::string name(); + std::string type_name(); + bool has_default_value(); + bool is_nullable_type(); + std::string default_value(); + std::string number(); + std::string message_or_group(); + std::string capitalized_type_name(); + std::string field_ordinal(); + + private: + std::string GetStringDefaultValueInternal(); + std::string GetBytesDefaultValueInternal(); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorBase); +}; + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_FIELD_BASE_H__ + diff --git a/src/google/protobuf/compiler/csharp/csharp_generator.cc b/src/google/protobuf/compiler/csharp/csharp_generator.cc new file mode 100644 index 00000000..64c4bd7d --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_generator.cc @@ -0,0 +1,96 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <sstream> + +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/compiler/plugin.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/io/zero_copy_stream.h> + +#include <google/protobuf/compiler/csharp/csharp_generator.h> +#include <google/protobuf/compiler/csharp/csharp_umbrella_class.h> +#include <google/protobuf/compiler/csharp/csharp_helpers.h> +#include <google/protobuf/compiler/csharp/csharp_writer.h> + +using google::protobuf::internal::scoped_ptr; + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +std::string GetOutputFile(const google::protobuf::FileDescriptor* file, const std::string file_extension) +{ + return GetFileUmbrellaClassname(file) + file_extension; +} + +void GenerateFile(const google::protobuf::FileDescriptor* file, + Writer* writer) { + UmbrellaClassGenerator umbrellaGenerator(file); + umbrellaGenerator.Generate(writer); +} + +bool Generator::Generate( + const FileDescriptor* file, + const string& parameter, + GeneratorContext* generator_context, + string* error) const { + + vector<pair<string, string> > options; + ParseGeneratorParameter(parameter, &options); + + std::string file_extension = ".cs"; + for (int i = 0; i < options.size(); i++) { + if (options[i].first == "file_extension") { + file_extension = options[i].second; + } else { + *error = "Unknown generator option: " + options[i].first; + return false; + } + } + + std::string filename = GetOutputFile(file, file_extension); + scoped_ptr<io::ZeroCopyOutputStream> output( + generator_context->Open(filename)); + io::Printer printer(output.get(), '$'); + Writer writer(&printer); + + GenerateFile(file, &writer); + + return true; +} + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/csharp/csharp_generator.h b/src/google/protobuf/compiler/csharp/csharp_generator.h new file mode 100644 index 00000000..9b54e914 --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_generator.h @@ -0,0 +1,58 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_GENERATOR_H__ +#define GOOGLE_PROTOBUF_COMPILER_CSHARP_GENERATOR_H__ + +#include <string> + +#include <google/protobuf/compiler/code_generator.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +class LIBPROTOC_EXPORT Generator + : public google::protobuf::compiler::CodeGenerator { + virtual bool Generate( + const FileDescriptor* file, + const string& parameter, + GeneratorContext* generator_context, + string* error) const; +}; + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_GENERATOR_H__ + diff --git a/src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc b/src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc new file mode 100644 index 00000000..7ef7df42 --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc @@ -0,0 +1,54 @@ +// 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 <google/protobuf/compiler/ruby/ruby_generator.h> +#include <google/protobuf/compiler/command_line_interface.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/io/printer.h> + +#include <google/protobuf/testing/googletest.h> +#include <gtest/gtest.h> +#include <google/protobuf/testing/file.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { +namespace { + +// TODO(jtattermusch): add some tests. + +} // namespace +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/csharp/csharp_helpers.cc b/src/google/protobuf/compiler/csharp/csharp_helpers.cc new file mode 100644 index 00000000..76e2c850 --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_helpers.cc @@ -0,0 +1,421 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <algorithm> +#include <google/protobuf/stubs/hash.h> +#include <limits> +#include <vector> + +#include <google/protobuf/compiler/csharp/csharp_helpers.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/substitute.h> + +#include <google/protobuf/compiler/csharp/csharp_field_base.h> +#include <google/protobuf/compiler/csharp/csharp_enum_field.h> +#include <google/protobuf/compiler/csharp/csharp_message_field.h> +#include <google/protobuf/compiler/csharp/csharp_primitive_field.h> +#include <google/protobuf/compiler/csharp/csharp_repeated_enum_field.h> +#include <google/protobuf/compiler/csharp/csharp_repeated_message_field.h> +#include <google/protobuf/compiler/csharp/csharp_repeated_primitive_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 descriptor->package(); +} + +std::string GetUmbrellaClassNameInternal(const std::string& proto_file) { + int lastslash = proto_file.find_last_of("/"); + std::string base = proto_file.substr(lastslash + 1); + return UnderscoresToPascalCase(StripDotProto(base)); +} + +std::string GetFileUmbrellaClassname(const FileDescriptor* descriptor) { + // umbrella_classname can no longer be set using message option. + return GetUmbrellaClassNameInternal(descriptor->name()); +} + +std::string GetFileUmbrellaNamespace(const FileDescriptor* descriptor) { + // TODO(jtattermusch): reintroduce csharp_umbrella_namespace option + bool collision = false; + std::string umbrella_classname = GetFileUmbrellaClassname(descriptor); + for(int i = 0; i < descriptor->message_type_count(); i++) { + if (descriptor->message_type(i)->name() == umbrella_classname) { + collision = true; + break; + } + } + for (int i = 0; i < descriptor->service_count(); i++) { + if (descriptor->service(i)->name() == umbrella_classname) { + collision = true; + break; + } + } + for (int i = 0; i < descriptor->enum_type_count(); i++) { + if (descriptor->enum_type(i)->name() == umbrella_classname) { + collision = true; + break; + } + } + return collision ? "Proto" : ""; +} + +// TODO(jtattermusch): can we reuse a utility function? +std::string UnderscoresToCamelCase(const std::string& input, + bool cap_next_letter) { + 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 UnderscoresToPascalCase(const std::string& input) { + return UnderscoresToCamelCase(input, true); +} + +std::string ToCSharpName(const std::string& name, const FileDescriptor* file) { + std::string result = GetFileNamespace(file); + if (result != "") { + result += '.'; + } + 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.", false); + return "global::" + result; +} + + + +std::string GetFullUmbrellaClassName(const FileDescriptor* descriptor) { + std::string result = GetFileNamespace(descriptor); + if (!result.empty()) { + result += '.'; + } + result += GetQualifiedUmbrellaClassName(descriptor); + return "global::" + result; +} + +std::string GetQualifiedUmbrellaClassName(const FileDescriptor* descriptor) { + std::string umbrellaNamespace = GetFileUmbrellaNamespace(descriptor); + std::string umbrellaClassname = GetFileUmbrellaClassname(descriptor); + + std::string fullName = umbrellaClassname; + if (!umbrellaNamespace.empty()) { + fullName = umbrellaNamespace + "." + umbrellaClassname; + } + return fullName; +} + +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)); + if (property_name == descriptor->containing_type()->name()) { + property_name += "_"; + } + return property_name; +} + +// 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 fieldOrdinal) { + switch (descriptor->type()) { + case FieldDescriptor::TYPE_GROUP: + case FieldDescriptor::TYPE_MESSAGE: + if (descriptor->is_repeated()) { + return new RepeatedMessageFieldGenerator(descriptor, fieldOrdinal); + } else { + if (descriptor->containing_oneof()) { + return new MessageOneofFieldGenerator(descriptor, fieldOrdinal); + } else { + return new MessageFieldGenerator(descriptor, fieldOrdinal); + } + } + case FieldDescriptor::TYPE_ENUM: + if (descriptor->is_repeated()) { + return new RepeatedEnumFieldGenerator(descriptor, fieldOrdinal); + } else { + if (descriptor->containing_oneof()) { + return new EnumOneofFieldGenerator(descriptor, fieldOrdinal); + } else { + return new EnumFieldGenerator(descriptor, fieldOrdinal); + } + } + default: + if (descriptor->is_repeated()) { + return new RepeatedPrimitiveFieldGenerator(descriptor, fieldOrdinal); + } else { + if (descriptor->containing_oneof()) { + return new PrimitiveOneofFieldGenerator(descriptor, fieldOrdinal); + } else { + return new PrimitiveFieldGenerator(descriptor, fieldOrdinal); + } + } + } +} + +bool HasRequiredFields(const Descriptor* descriptor, std::set<const Descriptor*>* already_seen) { + if (already_seen->find(descriptor) != already_seen->end()) { + // 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(descriptor); + + // 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 (descriptor->extension_count() > 0) { + return true; + } + + for (int i = 0; i < descriptor->field_count(); i++) { + const FieldDescriptor* field = descriptor->field(i); + if (field->is_required()) { + return true; + } + if (GetCSharpType(field->type()) == CSHARPTYPE_MESSAGE) { + if (HasRequiredFields(field->message_type(), already_seen)) { + return true; + } + } + } + return false; +} + +bool HasRequiredFields(const Descriptor* descriptor) { + std::set<const Descriptor*> already_seen; + return HasRequiredFields(descriptor, &already_seen); +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/csharp/csharp_helpers.h b/src/google/protobuf/compiler/csharp/csharp_helpers.h new file mode 100644 index 00000000..bc77f43a --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_helpers.h @@ -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. + +// 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 <google/protobuf/descriptor.pb.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/io/printer.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +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); + +std::string GetFileNamespace(const FileDescriptor* descriptor); +std::string GetFileUmbrellaClassname(const FileDescriptor* descriptor); +std::string GetFileUmbrellaNamespace(const FileDescriptor* descriptor); + +std::string GetFullUmbrellaClassName(const FileDescriptor* descriptor); + +std::string GetQualifiedUmbrellaClassName(const FileDescriptor* descriptor); + +std::string GetClassName(const Descriptor* 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); + +std::string UnderscoresToPascalCase(const std::string& input); + +// 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 fieldOrdinal); + +bool HasRequiredFields(const Descriptor* descriptor); + +inline bool SupportFieldPresence(const FileDescriptor* file) { + return file->syntax() != FileDescriptor::SYNTAX_PROTO3; +} + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_HELPERS_H__ diff --git a/src/google/protobuf/compiler/csharp/csharp_message.cc b/src/google/protobuf/compiler/csharp/csharp_message.cc new file mode 100644 index 00000000..22681235 --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_message.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. + +#include <sstream> +#include <algorithm> + +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/compiler/plugin.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/wire_format_lite.h> + +#include <google/protobuf/compiler/csharp/csharp_enum.h> +#include <google/protobuf/compiler/csharp/csharp_extension.h> +#include <google/protobuf/compiler/csharp/csharp_message.h> +#include <google/protobuf/compiler/csharp/csharp_helpers.h> +#include <google/protobuf/compiler/csharp/csharp_field_base.h> +#include <google/protobuf/compiler/csharp/csharp_writer.h> + +using google::protobuf::internal::scoped_ptr; + +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) + : SourceGeneratorBase(descriptor->file()), + descriptor_(descriptor) { + + // sorted field names + for (int i = 0; i < descriptor_->field_count(); i++) { + field_names_.push_back(descriptor_->field(i)->name()); + } + std::sort(field_names_.begin(), field_names_.end()); + + // 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); +} + +MessageGenerator::~MessageGenerator() { +} + +std::string MessageGenerator::class_name() { + return descriptor_->name(); +} + +std::string MessageGenerator::full_class_name() { + return GetClassName(descriptor_); +} + +const std::vector<std::string>& MessageGenerator::field_names() { + return field_names_; +} + +const std::vector<const FieldDescriptor*>& MessageGenerator::fields_by_number() { + return fields_by_number_; +} + +/// 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 GetUniqueFileScopeIdentifier(const Descriptor* descriptor) { + std::string result = descriptor->full_name(); + std::replace(result.begin(), result.end(), '.', '_'); + return "static_" + result; +} + +void MessageGenerator::GenerateStaticVariables(Writer* writer) { + // Because descriptor.proto (Google.ProtocolBuffers.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 proto-descriptor class. This way, they will be initialized in + // a deterministic order. + + std::string identifier = GetUniqueFileScopeIdentifier(descriptor_); + + if (!use_lite_runtime()) { + // The descriptor for this type. + std::string access = "internal"; + writer->WriteLine( + "$0$ static pbd::MessageDescriptor internal__$1$__Descriptor;", access, + identifier); + writer->WriteLine( + "$0$ static pb::FieldAccess.FieldAccessorTable<$1$, $1$.Builder> internal__$2$__FieldAccessorTable;", + access, full_class_name(), identifier); + } + + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + MessageGenerator messageGenerator(descriptor_->nested_type(i)); + messageGenerator.GenerateStaticVariables(writer); + } +} + +void MessageGenerator::GenerateStaticVariableInitializers(Writer* writer) { + std::string identifier = GetUniqueFileScopeIdentifier(descriptor_); + + if (!use_lite_runtime()) { + writer->Write("internal__$0$__Descriptor = ", identifier); + + if (!descriptor_->containing_type()) { + writer->WriteLine("Descriptor.MessageTypes[$0$];", + SimpleItoa(descriptor_->index())); + } else { + writer->WriteLine( + "internal__$0$__Descriptor.NestedTypes[$1$];", + GetUniqueFileScopeIdentifier(descriptor_->containing_type()), + SimpleItoa(descriptor_->index())); + } + + writer->WriteLine("internal__$0$__FieldAccessorTable = ", identifier); + writer->WriteLine( + " new pb::FieldAccess.FieldAccessorTable<$1$, $1$.Builder>(internal__$0$__Descriptor,", + identifier, full_class_name()); + writer->Write(" new string[] { "); + for (int i = 0; i < descriptor_->field_count(); i++) { + writer->Write("\"$0$\", ", GetPropertyName(descriptor_->field(i))); + } + for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { + writer->Write("\"$0$\", ", + UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true)); + } + writer->WriteLine("});"); + } + + // Generate static member initializers for all nested types. + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + MessageGenerator messageGenerator(descriptor_->nested_type(i)); + messageGenerator.GenerateStaticVariableInitializers(writer); + } + + for (int i = 0; i < descriptor_->extension_count(); i++) { + ExtensionGenerator extensionGenerator(descriptor_->extension(i)); + extensionGenerator.GenerateStaticVariableInitializers(writer); + } +} + +void MessageGenerator::Generate(Writer* writer) { + writer->WriteLine( + "[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]"); + WriteGeneratedCodeAttributes(writer); + writer->WriteLine( + "$0$ sealed partial class $1$ : pb::$2$Message$3$<$1$, $1$.Builder> {", + class_access_level(), class_name(), + descriptor_->extension_range_count() > 0 ? "Extendable" : "Generated", + runtime_suffix()); + writer->Indent(); + writer->WriteLine("private $0$() { }", class_name()); // Private ctor. + // Must call MakeReadOnly() to make sure all lists are made read-only + writer->WriteLine( + "private static readonly $0$ defaultInstance = new $0$().MakeReadOnly();", + class_name()); + + if (optimize_speed()) { + writer->WriteLine( + "private static readonly string[] _$0$FieldNames = new string[] { $2$$1$$2$ };", + UnderscoresToCamelCase(class_name(), false), + JoinStrings(field_names(), "\", \""), + field_names().size() > 0 ? "\"" : ""); + std::vector<std::string> tags; + for (int i = 0; i < field_names().size(); i++) { + uint32 tag = internal::WireFormat::MakeTag( + descriptor_->FindFieldByName(field_names()[i])); + tags.push_back(SimpleItoa(tag)); + } + writer->WriteLine( + "private static readonly uint[] _$0$FieldTags = new uint[] { $1$ };", + UnderscoresToCamelCase(class_name(), false), JoinStrings(tags, ", ")); + } + writer->WriteLine("public static $0$ DefaultInstance {", class_name()); + writer->WriteLine(" get { return defaultInstance; }"); + writer->WriteLine("}"); + writer->WriteLine(); + writer->WriteLine("public override $0$ DefaultInstanceForType {", + class_name()); + writer->WriteLine(" get { return DefaultInstance; }"); + writer->WriteLine("}"); + writer->WriteLine(); + writer->WriteLine("protected override $0$ ThisMessage {", class_name()); + writer->WriteLine(" get { return this; }"); + writer->WriteLine("}"); + writer->WriteLine(); + if (!use_lite_runtime()) { + writer->WriteLine("public static pbd::MessageDescriptor Descriptor {"); + writer->WriteLine(" get { return $0$.internal__$1$__Descriptor; }", + GetFullUmbrellaClassName(descriptor_->file()), + GetUniqueFileScopeIdentifier(descriptor_)); + writer->WriteLine("}"); + writer->WriteLine(); + writer->WriteLine( + "protected override pb::FieldAccess.FieldAccessorTable<$0$, $0$.Builder> InternalFieldAccessors {", + class_name()); + writer->WriteLine(" get { return $0$.internal__$1$__FieldAccessorTable; }", + GetFullUmbrellaClassName(descriptor_->file()), + GetUniqueFileScopeIdentifier(descriptor_)); + writer->WriteLine("}"); + writer->WriteLine(); + } + + // Extensions don't need to go in an extra nested type + for (int i = 0; i < descriptor_->extension_count(); i++) { + ExtensionGenerator extensionGenerator(descriptor_->extension(i)); + extensionGenerator.Generate(writer); + } + + if (descriptor_->enum_type_count() + descriptor_->nested_type_count() > 0) { + writer->WriteLine("#region Nested types"); + writer->WriteLine( + "[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]"); + WriteGeneratedCodeAttributes(writer); + writer->WriteLine("public static partial class Types {"); + writer->Indent(); + for (int i = 0; i < descriptor_->enum_type_count(); i++) { + EnumGenerator enumGenerator(descriptor_->enum_type(i)); + enumGenerator.Generate(writer); + } + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + MessageGenerator messageGenerator(descriptor_->nested_type(i)); + messageGenerator.Generate(writer); + } + writer->Outdent(); + writer->WriteLine("}"); + writer->WriteLine("#endregion"); + writer->WriteLine(); + } + + // oneof + for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { + string name = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false); + string property_name = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true); + writer->WriteLine("private object $0$_;", name); + writer->WriteLine("public enum $0$OneofCase {", property_name); + writer->Indent(); + for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { + const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); + writer->WriteLine("$0$ = $1$,", + GetPropertyName(field), + SimpleItoa(field->number())); + } + writer->WriteLine("None = 0,"); + writer->Outdent(); + writer->WriteLine("}"); + writer->WriteLine("private $0$OneofCase $1$Case_ = $0$OneofCase.None;", + property_name, name); + writer->WriteLine("public $0$OneofCase $0$Case {", property_name); + writer->WriteLine(" get { return $0$Case_; }", name); + writer->WriteLine("}"); + writer->WriteLine(); + } + + // Fields + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* fieldDescriptor = descriptor_->field(i); + + // Rats: we lose the debug comment here :( + writer->WriteLine("public const int $0$ = $1$;", + GetFieldConstantName(fieldDescriptor), + SimpleItoa(fieldDescriptor->number())); + scoped_ptr<FieldGeneratorBase> generator( + CreateFieldGeneratorInternal(fieldDescriptor)); + generator->GenerateMembers(writer); + writer->WriteLine(); + } + + if (optimize_speed()) { + if (SupportFieldPresence(descriptor_->file())) { + GenerateIsInitialized(writer); + } + GenerateMessageSerializationMethods(writer); + } + if (use_lite_runtime()) { + GenerateLiteRuntimeMethods(writer); + } + + GenerateParseFromMethods(writer); + GenerateBuilder(writer); + + // Force the static initialization code for the file to run, since it may + // initialize static variables declared in this class. + writer->WriteLine("static $0$() {", class_name()); + // We call object.ReferenceEquals() just to make it a valid statement on its own. + // Another option would be GetType(), but that causes problems in DescriptorProtoFile, + // where the bootstrapping is somewhat recursive - type initializers call + // each other, effectively. We temporarily see Descriptor as null. + writer->WriteLine(" object.ReferenceEquals($0$.Descriptor, null);", + GetFullUmbrellaClassName(descriptor_->file())); + writer->WriteLine("}"); + + writer->Outdent(); + writer->WriteLine("}"); + writer->WriteLine(); + +} + +void MessageGenerator::GenerateLiteRuntimeMethods(Writer* writer) { + bool callbase = descriptor_->extension_range_count() > 0; + writer->WriteLine("#region Lite runtime methods"); + writer->WriteLine("public override int GetHashCode() {"); + writer->Indent(); + writer->WriteLine("int hash = GetType().GetHashCode();"); + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + if (field->containing_oneof() == NULL) { + scoped_ptr<FieldGeneratorBase> generator( + CreateFieldGeneratorInternal(field)); + generator->WriteHash(writer); + } + } + for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { + string name = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false); + string property_name = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true); + writer->WriteLine("if ($0$Case_ != $1$OneofCase.None) {", name, property_name); + writer->WriteLine(" hash ^= $0$_.GetHashCode();", name); + writer->WriteLine("}"); + } + if (callbase) { + writer->WriteLine("hash ^= base.GetHashCode();"); + } + writer->WriteLine("return hash;"); + writer->Outdent(); + writer->WriteLine("}"); + writer->WriteLine(); + + writer->WriteLine("public override bool Equals(object obj) {"); + writer->Indent(); + writer->WriteLine("$0$ other = obj as $0$;", class_name()); + writer->WriteLine("if (other == null) return false;"); + for (int i = 0; i < descriptor_->field_count(); i++) { + scoped_ptr<FieldGeneratorBase> generator( + CreateFieldGeneratorInternal(descriptor_->field(i))); + generator->WriteEquals(writer); + } + if (callbase) { + writer->WriteLine("if (!base.Equals(other)) return false;"); + } + writer->WriteLine("return true;"); + writer->Outdent(); + writer->WriteLine("}"); + writer->WriteLine(); + + writer->WriteLine( + "public override void PrintTo(global::System.IO.TextWriter writer) {"); + writer->Indent(); + + for (int i = 0; i < fields_by_number().size(); i++) { + scoped_ptr<FieldGeneratorBase> generator( + CreateFieldGeneratorInternal(fields_by_number()[i])); + generator->WriteToString(writer); + } + + if (callbase) { + writer->WriteLine("base.PrintTo(writer);"); + } + writer->Outdent(); + writer->WriteLine("}"); + writer->WriteLine("#endregion"); + writer->WriteLine(); +} + +bool CompareExtensionRangesStart(const Descriptor::ExtensionRange* r1, + const Descriptor::ExtensionRange* r2) { + return r1->start < r2->start; +} + +void MessageGenerator::GenerateMessageSerializationMethods(Writer* writer) { + std::vector<const Descriptor::ExtensionRange*> extension_ranges_sorted; + for (int i = 0; i < descriptor_->extension_range_count(); i++) { + extension_ranges_sorted.push_back(descriptor_->extension_range(i)); + } + std::sort(extension_ranges_sorted.begin(), extension_ranges_sorted.end(), + CompareExtensionRangesStart); + + writer->WriteLine( + "public override void WriteTo(pb::ICodedOutputStream output) {"); + writer->Indent(); + // Make sure we've computed the serialized length, so that packed fields are generated correctly. + writer->WriteLine("CalcSerializedSize();"); + writer->WriteLine("string[] field_names = _$0$FieldNames;", + UnderscoresToCamelCase(class_name(), false)); + if (descriptor_->extension_range_count()) { + writer->WriteLine( + "pb::ExtendableMessage$1$<$0$, $0$.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);", + class_name(), runtime_suffix()); + } + + // Merge the fields and the extension ranges, both sorted by field number. + for (int i = 0, j = 0; + i < fields_by_number().size() || j < extension_ranges_sorted.size();) { + if (i == fields_by_number().size()) { + GenerateSerializeOneExtensionRange(writer, extension_ranges_sorted[j++]); + } else if (j == extension_ranges_sorted.size()) { + GenerateSerializeOneField(writer, fields_by_number()[i++]); + } else if (fields_by_number()[i]->number() + < extension_ranges_sorted[j]->start) { + GenerateSerializeOneField(writer, fields_by_number()[i++]); + } else { + GenerateSerializeOneExtensionRange(writer, extension_ranges_sorted[j++]); + } + } + + if (!use_lite_runtime()) { + if (descriptor_->options().message_set_wire_format()) + { + writer->WriteLine("UnknownFields.WriteAsMessageSetTo(output);"); + } else { + writer->WriteLine("UnknownFields.WriteTo(output);"); + } + } + + writer->Outdent(); + writer->WriteLine("}"); + writer->WriteLine(); + writer->WriteLine("private int memoizedSerializedSize = -1;"); + writer->WriteLine("public override int SerializedSize {"); + writer->Indent(); + writer->WriteLine("get {"); + writer->Indent(); + writer->WriteLine("int size = memoizedSerializedSize;"); + writer->WriteLine("if (size != -1) return size;"); + writer->WriteLine("return CalcSerializedSize();"); + writer->Outdent(); + writer->WriteLine("}"); + writer->Outdent(); + writer->WriteLine("}"); + writer->WriteLine(); + + writer->WriteLine("private int CalcSerializedSize() {"); + writer->Indent(); + writer->WriteLine("int size = memoizedSerializedSize;"); + writer->WriteLine("if (size != -1) return size;"); + writer->WriteLine(); + writer->WriteLine("size = 0;"); + for (int i = 0; i < descriptor_->field_count(); i++) { + scoped_ptr<FieldGeneratorBase> generator( + CreateFieldGeneratorInternal(descriptor_->field(i))); + generator->GenerateSerializedSizeCode(writer); + } + if (descriptor_->extension_range_count() > 0) { + writer->WriteLine("size += ExtensionsSerializedSize;"); + } + + if (!use_lite_runtime()) { + if (descriptor_->options().message_set_wire_format()) { + writer->WriteLine("size += UnknownFields.SerializedSizeAsMessageSet;"); + } else { + writer->WriteLine("size += UnknownFields.SerializedSize;"); + } + } + writer->WriteLine("memoizedSerializedSize = size;"); + writer->WriteLine("return size;"); + writer->Outdent(); + writer->WriteLine("}"); +} + +void MessageGenerator::GenerateSerializeOneField( + Writer* writer, const FieldDescriptor* fieldDescriptor) { + scoped_ptr<FieldGeneratorBase> generator( + CreateFieldGeneratorInternal(fieldDescriptor)); + generator->GenerateSerializationCode(writer); +} + +void MessageGenerator::GenerateSerializeOneExtensionRange( + Writer* writer, const Descriptor::ExtensionRange* extensionRange) { + writer->WriteLine("extensionWriter.WriteUntil($0$, output);", + SimpleItoa(extensionRange->end)); +} + +void MessageGenerator::GenerateParseFromMethods(Writer* writer) { + // Note: These are separate from GenerateMessageSerializationMethods() + // because they need to be generated even for messages that are optimized + // for code size. + + writer->WriteLine("public static $0$ ParseFrom(pb::ByteString data) {", + class_name()); + writer->WriteLine( + " return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();"); + writer->WriteLine("}"); + writer->WriteLine( + "public static $0$ ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {", + class_name()); + writer->WriteLine( + " return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();"); + writer->WriteLine("}"); + writer->WriteLine("public static $0$ ParseFrom(byte[] data) {", class_name()); + writer->WriteLine( + " return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();"); + writer->WriteLine("}"); + writer->WriteLine( + "public static $0$ ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {", + class_name()); + writer->WriteLine( + " return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();"); + writer->WriteLine("}"); + writer->WriteLine( + "public static $0$ ParseFrom(global::System.IO.Stream input) {", + class_name()); + writer->WriteLine( + " return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();"); + writer->WriteLine("}"); + writer->WriteLine( + "public static $0$ ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {", + class_name()); + writer->WriteLine( + " return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();"); + writer->WriteLine("}"); + writer->WriteLine( + "public static $0$ ParseDelimitedFrom(global::System.IO.Stream input) {", + class_name()); + writer->WriteLine( + " return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();"); + writer->WriteLine("}"); + writer->WriteLine( + "public static $0$ ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {", + class_name()); + writer->WriteLine( + " return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();"); + writer->WriteLine("}"); + writer->WriteLine( + "public static $0$ ParseFrom(pb::ICodedInputStream input) {", + class_name()); + writer->WriteLine( + " return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();"); + writer->WriteLine("}"); + writer->WriteLine( + "public static $0$ ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {", + class_name()); + writer->WriteLine( + " return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();"); + writer->WriteLine("}"); +} + +void MessageGenerator::GenerateBuilder(Writer* writer) { + writer->WriteLine("private $0$ MakeReadOnly() {", class_name()); + writer->Indent(); + for (int i = 0; i < descriptor_->field_count(); i++) { + scoped_ptr<FieldGeneratorBase> generator( + CreateFieldGeneratorInternal(descriptor_->field(i))); + generator->GenerateBuildingCode(writer); + } + writer->WriteLine("return this;"); + writer->Outdent(); + writer->WriteLine("}"); + writer->WriteLine(); + + writer->WriteLine( + "public static Builder CreateBuilder() { return new Builder(); }"); + writer->WriteLine( + "public override Builder ToBuilder() { return CreateBuilder(this); }"); + writer->WriteLine( + "public override Builder CreateBuilderForType() { return new Builder(); }"); + writer->WriteLine("public static Builder CreateBuilder($0$ prototype) {", + class_name()); + writer->WriteLine(" return new Builder(prototype);"); + writer->WriteLine("}"); + writer->WriteLine(); + writer->WriteLine( + "[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]"); + WriteGeneratedCodeAttributes(writer); + writer->WriteLine( + "$0$ sealed partial class Builder : pb::$2$Builder$3$<$1$, Builder> {", + class_access_level(), class_name(), + descriptor_->extension_range_count() > 0 ? "Extendable" : "Generated", + runtime_suffix()); + writer->Indent(); + writer->WriteLine("protected override Builder ThisBuilder {"); + writer->WriteLine(" get { return this; }"); + writer->WriteLine("}"); + GenerateCommonBuilderMethods(writer); + if (optimize_speed()) { + GenerateBuilderParsingMethods(writer); + } + for (int i = 0; i < descriptor_->field_count(); i++) { + scoped_ptr<FieldGeneratorBase> generator( + CreateFieldGeneratorInternal(descriptor_->field(i))); + writer->WriteLine(); + // No field comment :( + generator->GenerateBuilderMembers(writer); + } + + // oneof + for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { + writer->WriteLine(); + string name = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false); + string property_name = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true); + writer->WriteLine("public $0$OneofCase $0$Case {", property_name); + writer->WriteLine(" get { return result.$0$Case_; }", name); + writer->WriteLine("}"); + writer->WriteLine("public Builder Clear$0$() {", property_name); + writer->WriteLine(" PrepareBuilder();"); + writer->WriteLine(" result.$0$_ = null;", name); + writer->WriteLine(" result.$0$Case_ = $1$OneofCase.None;", name, property_name); + writer->WriteLine(" return this;"); + writer->WriteLine("}"); + } + + writer->Outdent(); + writer->WriteLine("}"); +} + +void MessageGenerator::GenerateCommonBuilderMethods(Writer* writer) { + //default constructor + writer->WriteLine("public Builder() {"); + //Durring static initialization of message, DefaultInstance is expected to return null. + writer->WriteLine(" result = DefaultInstance;"); + writer->WriteLine(" resultIsReadOnly = true;"); + writer->WriteLine("}"); + //clone constructor + writer->WriteLine("internal Builder($0$ cloneFrom) {", class_name()); + writer->WriteLine(" result = cloneFrom;"); + writer->WriteLine(" resultIsReadOnly = true;"); + writer->WriteLine("}"); + writer->WriteLine(); + writer->WriteLine("private bool resultIsReadOnly;"); + writer->WriteLine("private $0$ result;", class_name()); + writer->WriteLine(); + writer->WriteLine("private $0$ PrepareBuilder() {", class_name()); + writer->WriteLine(" if (resultIsReadOnly) {"); + writer->WriteLine(" $0$ original = result;", class_name()); + writer->WriteLine(" result = new $0$();", class_name()); + writer->WriteLine(" resultIsReadOnly = false;"); + writer->WriteLine(" MergeFrom(original);"); + writer->WriteLine(" }"); + writer->WriteLine(" return result;"); + writer->WriteLine("}"); + writer->WriteLine(); + writer->WriteLine("public override bool IsInitialized {"); + writer->WriteLine(" get { return result.IsInitialized; }"); + writer->WriteLine("}"); + writer->WriteLine(); + writer->WriteLine("protected override $0$ MessageBeingBuilt {", class_name()); + writer->WriteLine(" get { return PrepareBuilder(); }"); + writer->WriteLine("}"); + writer->WriteLine(); + //Not actually expecting that DefaultInstance would ever be null here; however, we will ensure it does not break + writer->WriteLine("public override Builder Clear() {"); + writer->WriteLine(" result = DefaultInstance;"); + writer->WriteLine(" resultIsReadOnly = true;"); + writer->WriteLine(" return this;"); + writer->WriteLine("}"); + writer->WriteLine(); + writer->WriteLine("public override Builder Clone() {"); + writer->WriteLine(" if (resultIsReadOnly) {"); + writer->WriteLine(" return new Builder(result);"); + writer->WriteLine(" } else {"); + writer->WriteLine(" return new Builder().MergeFrom(result);"); + writer->WriteLine(" }"); + writer->WriteLine("}"); + writer->WriteLine(); + if (!use_lite_runtime()) { + writer->WriteLine( + "public override pbd::MessageDescriptor DescriptorForType {"); + writer->WriteLine(" get { return $0$.Descriptor; }", full_class_name()); + writer->WriteLine("}"); + writer->WriteLine(); + } + writer->WriteLine("public override $0$ DefaultInstanceForType {", + class_name()); + writer->WriteLine(" get { return $0$.DefaultInstance; }", full_class_name()); + writer->WriteLine("}"); + writer->WriteLine(); + + writer->WriteLine("public override $0$ BuildPartial() {", class_name()); + writer->Indent(); + writer->WriteLine("if (resultIsReadOnly) {"); + writer->WriteLine(" return result;"); + writer->WriteLine("}"); + writer->WriteLine("resultIsReadOnly = true;"); + writer->WriteLine("return result.MakeReadOnly();"); + writer->Outdent(); + writer->WriteLine("}"); + writer->WriteLine(); + + if (optimize_speed()) { + writer->WriteLine( + "public override Builder MergeFrom(pb::IMessage$0$ other) {", + runtime_suffix()); + writer->WriteLine(" if (other is $0$) {", class_name()); + writer->WriteLine(" return MergeFrom(($0$) other);", class_name()); + writer->WriteLine(" } else {"); + writer->WriteLine(" base.MergeFrom(other);"); + writer->WriteLine(" return this;"); + writer->WriteLine(" }"); + writer->WriteLine("}"); + writer->WriteLine(); + writer->WriteLine("public override Builder MergeFrom($0$ other) {", + class_name()); + // Optimization: If other is the default instance, we know none of its + // fields are set so we can skip the merge. + writer->Indent(); + writer->WriteLine("if (other == $0$.DefaultInstance) return this;", + full_class_name()); + writer->WriteLine("PrepareBuilder();"); + for (int i = 0; i < descriptor_->field_count(); i++) { + if (!descriptor_->field(i)->containing_oneof()) { + scoped_ptr<FieldGeneratorBase> generator( + CreateFieldGeneratorInternal(descriptor_->field(i))); + generator->GenerateMergingCode(writer); + } + } + + // Merge oneof fields + for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) { + string name = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false); + string property_name = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true); + writer->WriteLine("switch (other.$0$Case) {", property_name); + writer->Indent(); + for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { + const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); + writer->WriteLine("case $0$OneofCase.$1$: {", + property_name, GetPropertyName(field)); + if (field->type() == FieldDescriptor::TYPE_GROUP || + field->type() == FieldDescriptor::TYPE_MESSAGE) { + writer->WriteLine(" Merge$0$(other.$0$);", GetPropertyName(field)); + } else { + writer->WriteLine(" Set$0$(other.$0$);", GetPropertyName(field)); + } + writer->WriteLine(" break;"); + writer->WriteLine("}"); + } + writer->WriteLine("case $0$OneofCase.None: { break; }", property_name); + writer->Outdent(); + writer->WriteLine("}"); + } + + // if message type has extensions + if (descriptor_->extension_range_count() > 0) { + writer->WriteLine(" this.MergeExtensionFields(other);"); + } + if (!use_lite_runtime()) { + writer->WriteLine("this.MergeUnknownFields(other.UnknownFields);"); + } + writer->WriteLine("return this;"); + writer->Outdent(); + writer->WriteLine("}"); + writer->WriteLine(); + } + +} + +void MessageGenerator::GenerateBuilderParsingMethods(Writer* writer) { + writer->WriteLine( + "public override Builder MergeFrom(pb::ICodedInputStream input) {"); + writer->WriteLine(" return MergeFrom(input, pb::ExtensionRegistry.Empty);"); + writer->WriteLine("}"); + writer->WriteLine(); + writer->WriteLine( + "public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {"); + writer->Indent(); + writer->WriteLine("PrepareBuilder();"); + if (!use_lite_runtime()) { + writer->WriteLine("pb::UnknownFieldSet.Builder unknownFields = null;"); + } + writer->WriteLine("uint tag;"); + writer->WriteLine("string field_name;"); + writer->WriteLine("while (input.ReadTag(out tag, out field_name)) {"); + writer->Indent(); + writer->WriteLine("if(tag == 0 && field_name != null) {"); + writer->Indent(); + //if you change from StringComparer.Ordinal, the array sort in FieldNames { get; } must also change + writer->WriteLine( + "int field_ordinal = global::System.Array.BinarySearch(_$0$FieldNames, field_name, global::System.StringComparer.Ordinal);", + UnderscoresToCamelCase(class_name(), false)); + writer->WriteLine("if(field_ordinal >= 0)"); + writer->WriteLine(" tag = _$0$FieldTags[field_ordinal];", + UnderscoresToCamelCase(class_name(), false)); + writer->WriteLine("else {"); + if (!use_lite_runtime()) { + writer->WriteLine(" if (unknownFields == null) {"); // First unknown field - create builder now + writer->WriteLine( + " unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);"); + writer->WriteLine(" }"); + } + writer->WriteLine( + " ParseUnknownField(input, $0$extensionRegistry, tag, field_name);", + use_lite_runtime() ? "" : "unknownFields, "); + writer->WriteLine(" continue;"); + writer->WriteLine("}"); + writer->Outdent(); + writer->WriteLine("}"); + + writer->WriteLine("switch (tag) {"); + writer->Indent(); + writer->WriteLine("case 0: {"); // 0 signals EOF / limit reached + writer->WriteLine(" throw pb::InvalidProtocolBufferException.InvalidTag();"); + writer->WriteLine("}"); + writer->WriteLine("default: {"); + writer->WriteLine(" if (pb::WireFormat.IsEndGroupTag(tag)) {"); + if (!use_lite_runtime()) { + writer->WriteLine(" if (unknownFields != null) {"); + writer->WriteLine(" this.UnknownFields = unknownFields.Build();"); + writer->WriteLine(" }"); + } + writer->WriteLine(" return this;"); // it's an endgroup tag + writer->WriteLine(" }"); + if (!use_lite_runtime()) { + writer->WriteLine(" if (unknownFields == null) {"); // First unknown field - create builder now + writer->WriteLine( + " unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);"); + writer->WriteLine(" }"); + } + writer->WriteLine( + " ParseUnknownField(input, $0$extensionRegistry, tag, field_name);", + use_lite_runtime() ? "" : "unknownFields, "); + writer->WriteLine(" break;"); + writer->WriteLine("}"); + + 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); + if (field->is_repeated() + && (wt == internal::WireFormatLite::WIRETYPE_VARINT + || wt == internal::WireFormatLite::WIRETYPE_FIXED32 + || wt == internal::WireFormatLite::WIRETYPE_FIXED64)) { + writer->WriteLine( + "case $0$:", + SimpleItoa( + internal::WireFormatLite::MakeTag( + field->number(), + internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED))); + } + + writer->WriteLine("case $0$: {", SimpleItoa(tag)); + writer->Indent(); + scoped_ptr<FieldGeneratorBase> generator( + CreateFieldGeneratorInternal(field)); + generator->GenerateParsingCode(writer); + writer->WriteLine("break;"); + writer->Outdent(); + writer->WriteLine("}"); + } + + writer->Outdent(); + writer->WriteLine("}"); + writer->Outdent(); + writer->WriteLine("}"); + writer->WriteLine(); + if (!use_lite_runtime()) { + writer->WriteLine("if (unknownFields != null) {"); + writer->WriteLine(" this.UnknownFields = unknownFields.Build();"); + writer->WriteLine("}"); + } + writer->WriteLine("return this;"); + writer->Outdent(); + writer->WriteLine("}"); + writer->WriteLine(); +} + +void MessageGenerator::GenerateIsInitialized(Writer* writer) { + writer->WriteLine("public override bool IsInitialized {"); + writer->Indent(); + writer->WriteLine("get {"); + writer->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++) { + if (descriptor_->field(i)->is_required()) { + writer->WriteLine("if (!has$0$) return false;", + GetPropertyName(descriptor_->field(i))); + } + } + + // Now check that all embedded messages are initialized. + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + + if (field->type() != FieldDescriptor::TYPE_MESSAGE || + !HasRequiredFields(field->message_type())) + { + continue; + } + // TODO(jtattermusch): shouldn't we use GetPropertyName here? + string propertyName = UnderscoresToPascalCase(GetFieldName(field)); + if (field->is_repeated()) + { + writer->WriteLine("foreach ($0$ element in $1$List) {", + GetClassName(field->message_type()), + propertyName); + writer->WriteLine(" if (!element.IsInitialized) return false;"); + writer->WriteLine("}"); + } + else if (field->is_optional()) + { + writer->WriteLine("if (Has$0$) {", propertyName); + writer->WriteLine(" if (!$0$.IsInitialized) return false;", propertyName); + writer->WriteLine("}"); + } + else + { + writer->WriteLine("if (!$0$.IsInitialized) return false;", propertyName); + } + } + + if (descriptor_->extension_range_count() > 0) { + writer->WriteLine("if (!ExtensionsAreInitialized) return false;"); + } + writer->WriteLine("return true;"); + writer->Outdent(); + writer->WriteLine("}"); + writer->Outdent(); + writer->WriteLine("}"); + writer->WriteLine(); +} + +void MessageGenerator::GenerateExtensionRegistrationCode(Writer* writer) { + for (int i = 0; i < descriptor_->extension_count(); i++) { + ExtensionGenerator extensionGenerator(descriptor_->extension(i)); + extensionGenerator.GenerateExtensionRegistrationCode(writer); + } + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + MessageGenerator messageGenerator(descriptor_->nested_type(i)); + messageGenerator.GenerateExtensionRegistrationCode(writer); + } +} + +int MessageGenerator::GetFieldOrdinal(const FieldDescriptor* descriptor) { + for (int i = 0; i < field_names().size(); i++) { + if (field_names()[i] == descriptor->name()) { + return i; + } + } + GOOGLE_LOG(DFATAL)<< "Could not find ordinal for field " << descriptor->name(); + return -1; +} + +FieldGeneratorBase* MessageGenerator::CreateFieldGeneratorInternal( + const FieldDescriptor* descriptor) { + return CreateFieldGenerator(descriptor, GetFieldOrdinal(descriptor)); +} + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/csharp/csharp_message.h b/src/google/protobuf/compiler/csharp/csharp_message.h new file mode 100644 index 00000000..b8d15df0 --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_message.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_COMPILER_CSHARP_MESSAGE_H__ +#define GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_H__ + +#include <string> +#include <vector> + +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/compiler/csharp/csharp_source_generator_base.h> +#include <google/protobuf/compiler/csharp/csharp_helpers.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +class Writer; +class FieldGeneratorBase; + +class MessageGenerator : public SourceGeneratorBase { + public: + MessageGenerator(const Descriptor* descriptor); + ~MessageGenerator(); + + void GenerateStaticVariables(Writer* printer); + void GenerateStaticVariableInitializers(Writer* printer); + void GenerateExtensionRegistrationCode(Writer* printer); + void Generate(Writer* printer); + + private: + const Descriptor* descriptor_; + std::vector<std::string> field_names_; + std::vector<const FieldDescriptor*> fields_by_number_; + + void GenerateLiteRuntimeMethods(Writer* writer); + void GenerateMessageSerializationMethods(Writer* writer); + void GenerateSerializeOneField(Writer* writer, + const FieldDescriptor* fieldDescriptor); + void GenerateSerializeOneExtensionRange( + Writer* writer, const Descriptor::ExtensionRange* extendsionRange); + void GenerateParseFromMethods(Writer* writer); + void GenerateBuilder(Writer* writer); + void GenerateCommonBuilderMethods(Writer* writer); + void GenerateBuilderParsingMethods(Writer* writer); + void GenerateIsInitialized(Writer* writer); + + int GetFieldOrdinal(const FieldDescriptor* descriptor); + FieldGeneratorBase* CreateFieldGeneratorInternal( + const FieldDescriptor* descriptor); + + std::string class_name(); + std::string full_class_name(); + + // field names sorted alphabetically + const std::vector<std::string>& field_names(); + + // field descriptors sorted by number + const std::vector<const FieldDescriptor*>& fields_by_number(); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator); +}; + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_H__ + diff --git a/src/google/protobuf/compiler/csharp/csharp_message_field.cc b/src/google/protobuf/compiler/csharp/csharp_message_field.cc new file mode 100644 index 00000000..b533d735 --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_message_field.cc @@ -0,0 +1,297 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (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 <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/compiler/plugin.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/stubs/strutil.h> + +#include <google/protobuf/compiler/csharp/csharp_helpers.h> +#include <google/protobuf/compiler/csharp/csharp_message_field.h> +#include <google/protobuf/compiler/csharp/csharp_writer.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor, + int fieldOrdinal) + : FieldGeneratorBase(descriptor, fieldOrdinal) { + has_property_check = "has" + property_name(); +} + +MessageFieldGenerator::~MessageFieldGenerator() { + +} + +void MessageFieldGenerator::GenerateMembers(Writer* writer) { + writer->WriteLine("private bool has$0$;", property_name()); + writer->WriteLine("private $0$ $1$_;", type_name(), name()); + AddDeprecatedFlag(writer); + writer->WriteLine("public bool Has$0$ {", property_name()); + writer->WriteLine(" get { return has$0$; }", property_name()); + writer->WriteLine("}"); + AddDeprecatedFlag(writer); + writer->WriteLine("public $0$ $1$ {", type_name(), property_name()); + writer->WriteLine(" get { return $0$_ ?? $1$; }", name(), default_value()); + writer->WriteLine("}"); +} + +void MessageFieldGenerator::GenerateBuilderMembers(Writer* writer) { + AddDeprecatedFlag(writer); + writer->WriteLine("public bool Has$0$ {", property_name()); + writer->WriteLine(" get { return result.has$0$; }", property_name()); + writer->WriteLine("}"); + AddDeprecatedFlag(writer); + writer->WriteLine("public $0$ $1$ {", type_name(), property_name()); + writer->WriteLine(" get { return result.$0$; }", property_name()); + writer->WriteLine(" set { Set$0$(value); }", property_name()); + writer->WriteLine("}"); + AddDeprecatedFlag(writer); + writer->WriteLine("public Builder Set$0$($1$ value) {", property_name(), + type_name()); + AddNullCheck(writer); + writer->WriteLine(" PrepareBuilder();"); + writer->WriteLine(" result.has$0$ = true;", property_name()); + writer->WriteLine(" result.$0$_ = value;", name()); + writer->WriteLine(" return this;"); + writer->WriteLine("}"); + AddDeprecatedFlag(writer); + writer->WriteLine("public Builder Set$0$($1$.Builder builderForValue) {", + property_name(), type_name()); + AddNullCheck(writer, "builderForValue"); + writer->WriteLine(" PrepareBuilder();"); + writer->WriteLine(" result.has$0$ = true;", property_name()); + writer->WriteLine(" result.$0$_ = builderForValue.Build();", name()); + writer->WriteLine(" return this;"); + writer->WriteLine("}"); + AddDeprecatedFlag(writer); + writer->WriteLine("public Builder Merge$0$($1$ value) {", property_name(), + type_name()); + AddNullCheck(writer); + writer->WriteLine(" PrepareBuilder();"); + writer->WriteLine(" if (result.has$0$ &&", property_name()); + writer->WriteLine(" result.$0$_ != $1$) {", name(), default_value()); + writer->WriteLine( + " result.$0$_ = $1$.CreateBuilder(result.$0$_).MergeFrom(value).BuildPartial();", + name(), type_name()); + writer->WriteLine(" } else {"); + writer->WriteLine(" result.$0$_ = value;", name()); + writer->WriteLine(" }"); + writer->WriteLine(" result.has$0$ = true;", property_name()); + writer->WriteLine(" return this;"); + writer->WriteLine("}"); + AddDeprecatedFlag(writer); + writer->WriteLine("public Builder Clear$0$() {", property_name()); + writer->WriteLine(" PrepareBuilder();"); + writer->WriteLine(" result.has$0$ = false;", property_name()); + writer->WriteLine(" result.$0$_ = null;", name()); + writer->WriteLine(" return this;"); + writer->WriteLine("}"); +} + +void MessageFieldGenerator::GenerateMergingCode(Writer* writer) { + writer->WriteLine("if (other.Has$0$) {", property_name()); + writer->WriteLine(" Merge$0$(other.$0$);", property_name()); + writer->WriteLine("}"); +} + +void MessageFieldGenerator::GenerateBuildingCode(Writer* writer) { + // Nothing to do for singular fields +} + +void MessageFieldGenerator::GenerateParsingCode(Writer* writer) { + writer->WriteLine("$0$.Builder subBuilder = $0$.CreateBuilder();", + type_name()); + writer->WriteLine("if (result.has$0$) {", property_name()); + writer->WriteLine(" subBuilder.MergeFrom($0$);", property_name()); + writer->WriteLine("}"); + + if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) { + writer->WriteLine("input.ReadGroup($0$, subBuilder, extensionRegistry);", + number()); + } else { + writer->WriteLine("input.ReadMessage(subBuilder, extensionRegistry);"); + } + writer->WriteLine("$0$ = subBuilder.BuildPartial();", property_name()); +} + +void MessageFieldGenerator::GenerateSerializationCode(Writer* writer) { + writer->WriteLine("if ($0$) {", has_property_check); + writer->WriteLine(" output.Write$0$($1$, field_names[$3$], $2$);", + message_or_group(), number(), property_name(), + field_ordinal()); + writer->WriteLine("}"); +} + +void MessageFieldGenerator::GenerateSerializedSizeCode(Writer* writer) { + writer->WriteLine("if ($0$) {", has_property_check); + writer->WriteLine(" size += pb::CodedOutputStream.Compute$0$Size($1$, $2$);", + message_or_group(), number(), property_name()); + writer->WriteLine("}"); +} + +void MessageFieldGenerator::WriteHash(Writer* writer) { + writer->WriteLine("if (has$0$) hash ^= $1$_.GetHashCode();", property_name(), + name()); +} +void MessageFieldGenerator::WriteEquals(Writer* writer) { + writer->WriteLine( + "if (has$0$ != other.has$0$ || (has$0$ && !$1$_.Equals(other.$1$_))) return false;", + property_name(), name()); +} +void MessageFieldGenerator::WriteToString(Writer* writer) { + writer->WriteLine("PrintField(\"$2$\", has$0$, $1$_, writer);", + property_name(), name(), GetFieldName(descriptor_)); +} + +MessageOneofFieldGenerator::MessageOneofFieldGenerator(const FieldDescriptor* descriptor, + int fieldOrdinal) + : MessageFieldGenerator(descriptor, fieldOrdinal) { + has_property_check = oneof_name() + "Case_ == " + oneof_property_name() + + "OneofCase." + property_name(); +} + +MessageOneofFieldGenerator::~MessageOneofFieldGenerator() { + +} + +void MessageOneofFieldGenerator::GenerateMembers(Writer* writer) { + if (SupportFieldPresence(descriptor_->file())) { + AddDeprecatedFlag(writer); + writer->WriteLine("public bool Has$0$ {", property_name()); + writer->WriteLine(" get { return $0$; }", has_property_check); + writer->WriteLine("}"); + } + AddDeprecatedFlag(writer); + writer->WriteLine("public $0$ $1$ {", type_name(), property_name()); + writer->WriteLine(" get { return $0$ ? ($1$) $2$_ : $3$; }", + has_property_check, type_name(), oneof_name(), default_value()); + writer->WriteLine("}"); +} + +void MessageOneofFieldGenerator::GenerateBuilderMembers(Writer* writer) { + if (SupportFieldPresence(descriptor_->file())) { + AddDeprecatedFlag(writer); + writer->WriteLine("public bool Has$0$ {", property_name()); + writer->WriteLine(" get { return result.$0$; }", has_property_check); + writer->WriteLine("}"); + } + AddDeprecatedFlag(writer); + writer->WriteLine("public $0$ $1$ {", type_name(), property_name()); + writer->WriteLine(" get { return result.$0$ ? ($1$) result.$2$_ : $3$; }", + has_property_check, type_name(), oneof_name(), default_value()); + writer->WriteLine(" set { Set$0$(value); }", property_name()); + writer->WriteLine("}"); + AddDeprecatedFlag(writer); + writer->WriteLine("public Builder Set$0$($1$ value) {", property_name(), + type_name()); + AddNullCheck(writer); + writer->WriteLine(" PrepareBuilder();"); + writer->WriteLine(" result.$0$Case_ = $1$OneofCase.$2$;", + oneof_name(), oneof_property_name(), property_name()); + writer->WriteLine(" result.$0$_ = value;", oneof_name()); + writer->WriteLine(" return this;"); + writer->WriteLine("}"); + AddDeprecatedFlag(writer); + writer->WriteLine("public Builder Set$0$($1$.Builder builderForValue) {", + property_name(), type_name()); + AddNullCheck(writer, "builderForValue"); + writer->WriteLine(" PrepareBuilder();"); + writer->WriteLine(" result.$0$Case_ = $1$OneofCase.$2$;", + oneof_name(), oneof_property_name(), property_name()); + writer->WriteLine(" result.$0$_ = builderForValue.Build();", oneof_name()); + writer->WriteLine(" return this;"); + writer->WriteLine("}"); + AddDeprecatedFlag(writer); + writer->WriteLine("public Builder Merge$0$($1$ value) {", property_name(), + type_name()); + AddNullCheck(writer); + writer->WriteLine(" PrepareBuilder();"); + writer->WriteLine(" if (result.$0$ &&", has_property_check); + writer->WriteLine(" result.$0$ != $1$) {", property_name(), default_value()); + writer->WriteLine( + " result.$0$_ = $1$.CreateBuilder(result.$2$).MergeFrom(value).BuildPartial();", + oneof_name(), type_name(), property_name()); + writer->WriteLine(" } else {"); + writer->WriteLine(" result.$0$_ = value;", oneof_name()); + writer->WriteLine(" }"); + writer->WriteLine(" result.$0$Case_ = $1$OneofCase.$2$;", + oneof_name(), oneof_property_name(), property_name()); + writer->WriteLine(" return this;"); + writer->WriteLine("}"); + AddDeprecatedFlag(writer); + writer->WriteLine("public Builder Clear$0$() {", property_name()); + writer->WriteLine(" if (result.$0$) {", has_property_check); + writer->WriteLine(" PrepareBuilder();"); + writer->WriteLine(" result.$0$Case_ = $1$OneofCase.None;", + oneof_name(), oneof_property_name()); + writer->WriteLine(" result.$0$_ = null;", oneof_name()); + writer->WriteLine(" }"); + writer->WriteLine(" return this;"); + writer->WriteLine("}"); +} + +void MessageOneofFieldGenerator::GenerateParsingCode(Writer* writer) { + writer->WriteLine("$0$.Builder subBuilder = $0$.CreateBuilder();", + type_name()); + writer->WriteLine("if (result.$0$) {", has_property_check); + writer->WriteLine(" subBuilder.MergeFrom($0$);", property_name()); + writer->WriteLine("}"); + + if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) { + writer->WriteLine("input.ReadGroup($0$, subBuilder, extensionRegistry);", + number()); + } else { + writer->WriteLine("input.ReadMessage(subBuilder, extensionRegistry);"); + } + writer->WriteLine("result.$0$_ = subBuilder.BuildPartial();", oneof_name()); + writer->WriteLine("result.$0$Case_ = $1$OneofCase.$2$;", + oneof_name(), oneof_property_name(), property_name()); +} + +void MessageOneofFieldGenerator::WriteEquals(Writer* writer) { + writer->WriteLine("if (!$0$.Equals(other.$0$)) return false;", property_name()); +} +void MessageOneofFieldGenerator::WriteToString(Writer* writer) { + writer->WriteLine("PrintField(\"$0$\", $1$, $2$_, writer);", + descriptor_->name(), has_property_check, oneof_name()); +} + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/csharp/csharp_message_field.h b/src/google/protobuf/compiler/csharp/csharp_message_field.h new file mode 100644 index 00000000..d455ade5 --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_message_field.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_COMPILER_CSHARP_MESSAGE_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_FIELD_H__ + +#include <string> + +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/compiler/csharp/csharp_field_base.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +class Writer; + +class MessageFieldGenerator : public FieldGeneratorBase { + public: + MessageFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); + ~MessageFieldGenerator(); + + virtual void GenerateMembers(Writer* writer); + virtual void GenerateBuilderMembers(Writer* writer); + virtual void GenerateMergingCode(Writer* writer); + virtual void GenerateBuildingCode(Writer* writer); + virtual void GenerateParsingCode(Writer* writer); + virtual void GenerateSerializationCode(Writer* writer); + virtual void GenerateSerializedSizeCode(Writer* writer); + + virtual void WriteHash(Writer* writer); + virtual void WriteEquals(Writer* writer); + virtual void WriteToString(Writer* writer); + + protected: + string has_property_check; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator); +}; + +class MessageOneofFieldGenerator : public MessageFieldGenerator { + public: + MessageOneofFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); + ~MessageOneofFieldGenerator(); + + virtual void GenerateMembers(Writer* writer); + virtual void GenerateBuilderMembers(Writer* writer); + virtual void WriteEquals(Writer* writer); + virtual void WriteToString(Writer* writer); + virtual void GenerateParsingCode(Writer* writer); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageOneofFieldGenerator); +}; + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_FIELD_H__ + diff --git a/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc b/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc new file mode 100644 index 00000000..a54edfe3 --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc @@ -0,0 +1,254 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (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 <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/compiler/plugin.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/stubs/strutil.h> + +#include <google/protobuf/compiler/csharp/csharp_helpers.h> +#include <google/protobuf/compiler/csharp/csharp_primitive_field.h> +#include <google/protobuf/compiler/csharp/csharp_writer.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +PrimitiveFieldGenerator::PrimitiveFieldGenerator( + const FieldDescriptor* descriptor, int fieldOrdinal) + : FieldGeneratorBase(descriptor, fieldOrdinal) { + if (SupportFieldPresence(descriptor_->file())) { + has_property_check = "has" + property_name(); + } else { + has_property_check = property_name() + " != " + default_value(); + } +} + +PrimitiveFieldGenerator::~PrimitiveFieldGenerator() { + +} + +void PrimitiveFieldGenerator::GenerateMembers(Writer* writer) { + if (SupportFieldPresence(descriptor_->file())) { + writer->WriteLine("private bool has$0$;", property_name()); + } + writer->WriteLine("private $0$ $1$_$2$;", type_name(), name(), + has_default_value() ? " = " + default_value() : ""); + AddDeprecatedFlag(writer); + if (SupportFieldPresence(descriptor_->file())) { + writer->WriteLine("public bool Has$0$ {", property_name()); + writer->WriteLine(" get { return has$0$; }", property_name()); + writer->WriteLine("}"); + } + AddPublicMemberAttributes(writer); + writer->WriteLine("public $0$ $1$ {", type_name(), property_name()); + writer->WriteLine(" get { return $0$_; }", name()); + writer->WriteLine("}"); +} + +void PrimitiveFieldGenerator::GenerateBuilderMembers(Writer* writer) { + AddDeprecatedFlag(writer); + if (SupportFieldPresence(descriptor_->file())) { + writer->WriteLine("public bool Has$0$ {", property_name()); + writer->WriteLine(" get { return result.has$0$; }", property_name()); + writer->WriteLine("}"); + } + AddPublicMemberAttributes(writer); + writer->WriteLine("public $0$ $1$ {", type_name(), property_name()); + writer->WriteLine(" get { return result.$0$; }", property_name()); + writer->WriteLine(" set { Set$0$(value); }", property_name()); + writer->WriteLine("}"); + AddPublicMemberAttributes(writer); + writer->WriteLine("public Builder Set$0$($1$ value) {", property_name(), + type_name()); + AddNullCheck(writer); + writer->WriteLine(" PrepareBuilder();"); + if (SupportFieldPresence(descriptor_->file())) { + writer->WriteLine(" result.has$0$ = true;", property_name()); + } + writer->WriteLine(" result.$0$_ = value;", name()); + writer->WriteLine(" return this;"); + writer->WriteLine("}"); + AddDeprecatedFlag(writer); + writer->WriteLine("public Builder Clear$0$() {", property_name()); + writer->WriteLine(" PrepareBuilder();"); + if (SupportFieldPresence(descriptor_->file())) { + writer->WriteLine(" result.has$0$ = false;", property_name()); + } + writer->WriteLine(" result.$0$_ = $1$;", name(), default_value()); + writer->WriteLine(" return this;"); + writer->WriteLine("}"); +} + +void PrimitiveFieldGenerator::GenerateMergingCode(Writer* writer) { + if (SupportFieldPresence(descriptor_->file())) { + writer->WriteLine("if (other.Has$0$) {", property_name()); + } else { + writer->WriteLine("if (other.$0$ != $1$) {", property_name(), default_value()); + } + writer->WriteLine(" $0$ = other.$0$;", property_name()); + writer->WriteLine("}"); +} + +void PrimitiveFieldGenerator::GenerateBuildingCode(Writer* writer) { + // Nothing to do here for primitive types +} + +void PrimitiveFieldGenerator::GenerateParsingCode(Writer* writer) { + if (SupportFieldPresence(descriptor_->file())) { + writer->WriteLine("result.has$0$ = input.Read$1$(ref result.$2$_);", + property_name(), capitalized_type_name(), name()); + } else { + writer->WriteLine("input.Read$0$(ref result.$1$_);", + capitalized_type_name(), name()); + } +} + +void PrimitiveFieldGenerator::GenerateSerializationCode(Writer* writer) { + writer->WriteLine("if ($0$) {", has_property_check); + writer->WriteLine(" output.Write$0$($1$, field_names[$3$], $2$);", + capitalized_type_name(), number(), property_name(), + field_ordinal()); + writer->WriteLine("}"); +} + +void PrimitiveFieldGenerator::GenerateSerializedSizeCode(Writer* writer) { + writer->WriteLine("if ($0$) {", has_property_check); + writer->WriteLine(" size += pb::CodedOutputStream.Compute$0$Size($1$, $2$);", + capitalized_type_name(), number(), property_name()); + writer->WriteLine("}"); +} + +void PrimitiveFieldGenerator::WriteHash(Writer* writer) { + writer->WriteLine("if ($0$) {", has_property_check); + writer->WriteLine(" hash ^= $0$_.GetHashCode();", name()); + writer->WriteLine("}"); +} +void PrimitiveFieldGenerator::WriteEquals(Writer* writer) { + if (SupportFieldPresence(descriptor_->file())) { + writer->WriteLine( + "if (has$0$ != other.has$0$ || (has$0$ && !$1$_.Equals(other.$1$_))) return false;", + property_name(), name()); + } else { + writer->WriteLine( + "if (!$0$_.Equals(other.$0$_)) return false;", name()); + } +} +void PrimitiveFieldGenerator::WriteToString(Writer* writer) { + writer->WriteLine("PrintField(\"$0$\", $1$, $2$_, writer);", + descriptor_->name(), has_property_check, name()); +} + +PrimitiveOneofFieldGenerator::PrimitiveOneofFieldGenerator( + const FieldDescriptor* descriptor, int fieldOrdinal) + : PrimitiveFieldGenerator(descriptor, fieldOrdinal) { + has_property_check = oneof_name() + "Case_ == " + oneof_property_name() + + "OneofCase." + property_name(); +} + +PrimitiveOneofFieldGenerator::~PrimitiveOneofFieldGenerator() { +} + +void PrimitiveOneofFieldGenerator::GenerateMembers(Writer* writer) { + AddDeprecatedFlag(writer); + if (SupportFieldPresence(descriptor_->file())) { + writer->WriteLine("public bool Has$0$ {", property_name()); + writer->WriteLine(" get { return $0$; }", has_property_check); + writer->WriteLine("}"); + } + AddPublicMemberAttributes(writer); + writer->WriteLine("public $0$ $1$ {", type_name(), property_name()); + writer->WriteLine(" get { return $0$ ? ($1$) $2$_ : $3$; }", + has_property_check, type_name(), oneof_name(), default_value()); + writer->WriteLine("}"); +} + +void PrimitiveOneofFieldGenerator::GenerateBuilderMembers(Writer* writer) { + AddDeprecatedFlag(writer); + if (SupportFieldPresence(descriptor_->file())) { + writer->WriteLine("public bool Has$0$ {", property_name()); + writer->WriteLine(" get { return result.$0$; }", has_property_check); + writer->WriteLine("}"); + } + AddPublicMemberAttributes(writer); + writer->WriteLine("public $0$ $1$ {", type_name(), property_name()); + writer->WriteLine(" get { return result.$0$ ? ($1$) result.$2$_ : $3$; }", + has_property_check, type_name(), oneof_name(), default_value()); + writer->WriteLine(" set { Set$0$(value); }", property_name()); + writer->WriteLine("}"); + AddPublicMemberAttributes(writer); + writer->WriteLine("public Builder Set$0$($1$ value) {", property_name(), + type_name()); + AddNullCheck(writer); + writer->WriteLine(" PrepareBuilder();"); + writer->WriteLine(" result.$0$_ = value;", oneof_name()); + writer->WriteLine(" result.$0$Case_ = $1$OneofCase.$2$;", + oneof_name(), oneof_property_name(), property_name()); + writer->WriteLine(" return this;"); + writer->WriteLine("}"); + AddDeprecatedFlag(writer); + writer->WriteLine("public Builder Clear$0$() {", property_name()); + writer->WriteLine(" PrepareBuilder();"); + writer->WriteLine(" if (result.$0$) {", has_property_check); + writer->WriteLine(" result.$0$Case_ = $1$OneofCase.None;", + oneof_name(), oneof_property_name()); + writer->WriteLine(" }"); + writer->WriteLine(" return this;"); + writer->WriteLine("}"); +} + +void PrimitiveOneofFieldGenerator::WriteEquals(Writer* writer) { + writer->WriteLine("if (!$0$.Equals(other.$0$)) return false;", property_name()); +} +void PrimitiveOneofFieldGenerator::WriteToString(Writer* writer) { + writer->WriteLine("PrintField(\"$0$\", $1$, $2$_, writer);", + descriptor_->name(), has_property_check, oneof_name()); +} + +void PrimitiveOneofFieldGenerator::GenerateParsingCode(Writer* writer) { + writer->WriteLine("$0$ value = $1$;", type_name(), default_value()); + writer->WriteLine("if (input.Read$0$(ref value)) {", + capitalized_type_name()); + writer->WriteLine(" result.$0$_ = value;", oneof_name()); + writer->WriteLine(" result.$0$Case_ = $1$OneofCase.$2$;", + oneof_name(), oneof_property_name(), property_name()); + writer->WriteLine("}"); +} + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/csharp/csharp_primitive_field.h b/src/google/protobuf/compiler/csharp/csharp_primitive_field.h new file mode 100644 index 00000000..ecc6ed91 --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_primitive_field.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_COMPILER_CSHARP_PRIMITIVE_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_CSHARP_PRIMITIVE_FIELD_H__ + +#include <string> + +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/compiler/csharp/csharp_field_base.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +class Writer; + +class PrimitiveFieldGenerator : public FieldGeneratorBase { + public: + PrimitiveFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); + ~PrimitiveFieldGenerator(); + + virtual void GenerateMembers(Writer* writer); + virtual void GenerateBuilderMembers(Writer* writer); + virtual void GenerateMergingCode(Writer* writer); + virtual void GenerateBuildingCode(Writer* writer); + virtual void GenerateParsingCode(Writer* writer); + virtual void GenerateSerializationCode(Writer* writer); + virtual void GenerateSerializedSizeCode(Writer* writer); + + virtual void WriteHash(Writer* writer); + virtual void WriteEquals(Writer* writer); + virtual void WriteToString(Writer* writer); + + protected: + string has_property_check; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator); +}; + +class PrimitiveOneofFieldGenerator : public PrimitiveFieldGenerator { + public: + PrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); + ~PrimitiveOneofFieldGenerator(); + + virtual void GenerateMembers(Writer* writer); + virtual void GenerateBuilderMembers(Writer* writer); + virtual void WriteEquals(Writer* writer); + virtual void WriteToString(Writer* writer); + virtual void GenerateParsingCode(Writer* writer); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveOneofFieldGenerator); +}; + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_PRIMITIVE_FIELD_H__ + diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc b/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc new file mode 100644 index 00000000..cc8745ae --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc @@ -0,0 +1,226 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (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 <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/compiler/plugin.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/wire_format.h> + +#include <google/protobuf/compiler/csharp/csharp_helpers.h> +#include <google/protobuf/compiler/csharp/csharp_repeated_enum_field.h> +#include <google/protobuf/compiler/csharp/csharp_writer.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +RepeatedEnumFieldGenerator::RepeatedEnumFieldGenerator( + const FieldDescriptor* descriptor, int fieldOrdinal) + : FieldGeneratorBase(descriptor, fieldOrdinal) { +} + +RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() { + +} + +void RepeatedEnumFieldGenerator::GenerateMembers(Writer* writer) { + if (descriptor_->is_packed() && optimize_speed()) { + writer->WriteLine("private int $0$MemoizedSerializedSize;", name()); + } + writer->WriteLine( + "private pbc::PopsicleList<$0$> $1$_ = new pbc::PopsicleList<$0$>();", + type_name(), name()); + AddDeprecatedFlag(writer); + writer->WriteLine("public scg::IList<$0$> $1$List {", type_name(), + property_name()); + writer->WriteLine(" get { return pbc::Lists.AsReadOnly($0$_); }", name()); + writer->WriteLine("}"); + + // TODO(jonskeet): Redundant API calls? Possibly - include for portability though. Maybe create an option. + AddDeprecatedFlag(writer); + writer->WriteLine("public int $0$Count {", property_name()); + writer->WriteLine(" get { return $0$_.Count; }", name()); + writer->WriteLine("}"); + + AddDeprecatedFlag(writer); + writer->WriteLine("public $0$ Get$1$(int index) {", type_name(), + property_name()); + writer->WriteLine(" return $0$_[index];", name()); + writer->WriteLine("}"); +} + +void RepeatedEnumFieldGenerator::GenerateBuilderMembers(Writer* writer) { + // Note: We can return the original list here, because we make it unmodifiable when we build + // We return it via IPopsicleList so that collection initializers work more pleasantly. + AddDeprecatedFlag(writer); + writer->WriteLine("public pbc::IPopsicleList<$0$> $1$List {", type_name(), + property_name()); + writer->WriteLine(" get { return PrepareBuilder().$0$_; }", name()); + writer->WriteLine("}"); + AddDeprecatedFlag(writer); + writer->WriteLine("public int $0$Count {", property_name()); + writer->WriteLine(" get { return result.$0$Count; }", property_name()); + writer->WriteLine("}"); + AddDeprecatedFlag(writer); + writer->WriteLine("public $0$ Get$1$(int index) {", type_name(), + property_name()); + writer->WriteLine(" return result.Get$0$(index);", property_name()); + writer->WriteLine("}"); + AddDeprecatedFlag(writer); + writer->WriteLine("public Builder Set$0$(int index, $1$ value) {", + property_name(), type_name()); + writer->WriteLine(" PrepareBuilder();"); + writer->WriteLine(" result.$0$_[index] = value;", name()); + writer->WriteLine(" return this;"); + writer->WriteLine("}"); + AddDeprecatedFlag(writer); + writer->WriteLine("public Builder Add$0$($1$ value) {", property_name(), + type_name()); + writer->WriteLine(" PrepareBuilder();"); + writer->WriteLine(" result.$0$_.Add(value);", name(), type_name()); + writer->WriteLine(" return this;"); + writer->WriteLine("}"); + AddDeprecatedFlag(writer); + writer->WriteLine( + "public Builder AddRange$0$(scg::IEnumerable<$1$> values) {", + property_name(), type_name()); + writer->WriteLine(" PrepareBuilder();"); + writer->WriteLine(" result.$0$_.Add(values);", name()); + writer->WriteLine(" return this;"); + writer->WriteLine("}"); + AddDeprecatedFlag(writer); + writer->WriteLine("public Builder Clear$0$() {", property_name()); + writer->WriteLine(" PrepareBuilder();"); + writer->WriteLine(" result.$0$_.Clear();", name()); + writer->WriteLine(" return this;"); + writer->WriteLine("}"); +} + +void RepeatedEnumFieldGenerator::GenerateMergingCode(Writer* writer) { + writer->WriteLine("if (other.$0$_.Count != 0) {", name()); + writer->WriteLine(" result.$0$_.Add(other.$0$_);", name()); + writer->WriteLine("}"); +} + +void RepeatedEnumFieldGenerator::GenerateBuildingCode(Writer* writer) { + writer->WriteLine("$0$_.MakeReadOnly();", name()); +} + +void RepeatedEnumFieldGenerator::GenerateParsingCode(Writer* writer) { + writer->WriteLine("scg::ICollection<object> unknownItems;"); + writer->WriteLine( + "input.ReadEnumArray<$0$>(tag, field_name, result.$1$_, out unknownItems);", + type_name(), name()); + if (!use_lite_runtime()) { + writer->WriteLine("if (unknownItems != null) {"); + writer->WriteLine(" if (unknownFields == null) {"); + writer->WriteLine( + " unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);"); + writer->WriteLine(" }"); + writer->WriteLine(" foreach (object rawValue in unknownItems)"); + writer->WriteLine(" if (rawValue is int)"); + writer->WriteLine( + " unknownFields.MergeVarintField($0$, (ulong)(int)rawValue);", + number()); + writer->WriteLine("}"); + } +} + +void RepeatedEnumFieldGenerator::GenerateSerializationCode(Writer* writer) { + writer->WriteLine("if ($0$_.Count > 0) {", name()); + writer->Indent(); + if (descriptor_->is_packed()) { + writer->WriteLine( + "output.WritePackedEnumArray($0$, field_names[$2$], $1$MemoizedSerializedSize, $1$_);", + number(), name(), field_ordinal()); + } else { + writer->WriteLine("output.WriteEnumArray($0$, field_names[$2$], $1$_);", + number(), name(), field_ordinal()); + } + writer->Outdent(); + writer->WriteLine("}"); +} + +void RepeatedEnumFieldGenerator::GenerateSerializedSizeCode(Writer* writer) { + writer->WriteLine("{"); + writer->Indent(); + writer->WriteLine("int dataSize = 0;"); + writer->WriteLine("if ($0$_.Count > 0) {", name()); + writer->Indent(); + writer->WriteLine("foreach ($0$ element in $1$_) {", type_name(), name()); + writer->WriteLine( + " dataSize += pb::CodedOutputStream.ComputeEnumSizeNoTag((int) element);"); + writer->WriteLine("}"); + writer->WriteLine("size += dataSize;"); + int tagSize = internal::WireFormat::TagSize(descriptor_->number(), descriptor_->type()); + if (descriptor_->is_packed()) { + writer->WriteLine("size += $0$;", SimpleItoa(tagSize)); + writer->WriteLine( + "size += pb::CodedOutputStream.ComputeRawVarint32Size((uint) dataSize);"); + } else { + writer->WriteLine("size += $0$ * $1$_.Count;", SimpleItoa(tagSize), name()); + } + writer->Outdent(); + writer->WriteLine("}"); + // cache the data size for packed fields. + if (descriptor_->is_packed()) { + writer->WriteLine("$0$MemoizedSerializedSize = dataSize;", name()); + } + writer->Outdent(); + writer->WriteLine("}"); +} + +void RepeatedEnumFieldGenerator::WriteHash(Writer* writer) { + writer->WriteLine("foreach($0$ i in $1$_)", type_name(), name()); + writer->WriteLine(" hash ^= i.GetHashCode();"); +} + +void RepeatedEnumFieldGenerator::WriteEquals(Writer* writer) { + writer->WriteLine("if($0$_.Count != other.$0$_.Count) return false;", name()); + writer->WriteLine("for(int ix=0; ix < $0$_.Count; ix++)", name()); + writer->WriteLine(" if(!$0$_[ix].Equals(other.$0$_[ix])) return false;", + name()); +} + +void RepeatedEnumFieldGenerator::WriteToString(Writer* writer) { + writer->WriteLine("PrintField(\"$0$\", $1$_, writer);", descriptor_->name(), + name()); +} + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h b/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h new file mode 100644 index 00000000..c872131c --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.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_CSHARP_REPEATED_ENUM_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_ENUM_FIELD_H__ + +#include <string> + +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/compiler/csharp/csharp_field_base.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +class Writer; + +class RepeatedEnumFieldGenerator : public FieldGeneratorBase { + public: + RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); + ~RepeatedEnumFieldGenerator(); + + virtual void GenerateMembers(Writer* writer); + virtual void GenerateBuilderMembers(Writer* writer); + virtual void GenerateMergingCode(Writer* writer); + virtual void GenerateBuildingCode(Writer* writer); + virtual void GenerateParsingCode(Writer* writer); + virtual void GenerateSerializationCode(Writer* writer); + virtual void GenerateSerializedSizeCode(Writer* writer); + + virtual void WriteHash(Writer* writer); + virtual void WriteEquals(Writer* writer); + virtual void WriteToString(Writer* writer); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedEnumFieldGenerator); +}; + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_ENUM_FIELD_H__ + diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc new file mode 100644 index 00000000..2dfcd402 --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc @@ -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. + +#include <sstream> + +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/compiler/plugin.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/io/zero_copy_stream.h> + +#include <google/protobuf/compiler/csharp/csharp_helpers.h> +#include <google/protobuf/compiler/csharp/csharp_repeated_message_field.h> +#include <google/protobuf/compiler/csharp/csharp_writer.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator( + const FieldDescriptor* descriptor, int fieldOrdinal) + : FieldGeneratorBase(descriptor, fieldOrdinal) { +} + +RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() { + +} + +void RepeatedMessageFieldGenerator::GenerateMembers(Writer* writer) { + writer->WriteLine( + "private pbc::PopsicleList<$0$> $1$_ = new pbc::PopsicleList<$0$>();", + type_name(), name()); + AddDeprecatedFlag(writer); + writer->WriteLine("public scg::IList<$0$> $1$List {", type_name(), + property_name()); + writer->WriteLine(" get { return $0$_; }", name()); + writer->WriteLine("}"); + + // TODO(jonskeet): Redundant API calls? Possibly - include for portability though. Maybe create an option. + AddDeprecatedFlag(writer); + writer->WriteLine("public int $0$Count {", property_name()); + writer->WriteLine(" get { return $0$_.Count; }", name()); + writer->WriteLine("}"); + + AddDeprecatedFlag(writer); + writer->WriteLine("public $0$ Get$1$(int index) {", type_name(), + property_name()); + writer->WriteLine(" return $0$_[index];", name()); + writer->WriteLine("}"); +} + +void RepeatedMessageFieldGenerator::GenerateBuilderMembers(Writer* writer) { + // Note: We can return the original list here, because we make it unmodifiable when we build + // We return it via IPopsicleList so that collection initializers work more pleasantly. + AddDeprecatedFlag(writer); + writer->WriteLine("public pbc::IPopsicleList<$0$> $1$List {", type_name(), + property_name()); + writer->WriteLine(" get { return PrepareBuilder().$0$_; }", name()); + writer->WriteLine("}"); + AddDeprecatedFlag(writer); + writer->WriteLine("public int $0$Count {", property_name()); + writer->WriteLine(" get { return result.$0$Count; }", property_name()); + writer->WriteLine("}"); + AddDeprecatedFlag(writer); + writer->WriteLine("public $0$ Get$1$(int index) {", type_name(), + property_name()); + writer->WriteLine(" return result.Get$0$(index);", property_name()); + writer->WriteLine("}"); + AddDeprecatedFlag(writer); + writer->WriteLine("public Builder Set$0$(int index, $1$ value) {", + property_name(), type_name()); + AddNullCheck(writer); + writer->WriteLine(" PrepareBuilder();"); + writer->WriteLine(" result.$0$_[index] = value;", name()); + writer->WriteLine(" return this;"); + writer->WriteLine("}"); + // Extra overload for builder (just on messages) + AddDeprecatedFlag(writer); + writer->WriteLine( + "public Builder Set$0$(int index, $1$.Builder builderForValue) {", + property_name(), type_name()); + AddNullCheck(writer, "builderForValue"); + writer->WriteLine(" PrepareBuilder();"); + writer->WriteLine(" result.$0$_[index] = builderForValue.Build();", name()); + writer->WriteLine(" return this;"); + writer->WriteLine("}"); + AddDeprecatedFlag(writer); + writer->WriteLine("public Builder Add$0$($1$ value) {", property_name(), + type_name()); + AddNullCheck(writer); + writer->WriteLine(" PrepareBuilder();"); + writer->WriteLine(" result.$0$_.Add(value);", name(), type_name()); + writer->WriteLine(" return this;"); + writer->WriteLine("}"); + // Extra overload for builder (just on messages) + AddDeprecatedFlag(writer); + writer->WriteLine("public Builder Add$0$($1$.Builder builderForValue) {", + property_name(), type_name()); + AddNullCheck(writer, "builderForValue"); + writer->WriteLine(" PrepareBuilder();"); + writer->WriteLine(" result.$0$_.Add(builderForValue.Build());", name()); + writer->WriteLine(" return this;"); + writer->WriteLine("}"); + AddDeprecatedFlag(writer); + writer->WriteLine( + "public Builder AddRange$0$(scg::IEnumerable<$1$> values) {", + property_name(), type_name()); + writer->WriteLine(" PrepareBuilder();"); + writer->WriteLine(" result.$0$_.Add(values);", name()); + writer->WriteLine(" return this;"); + writer->WriteLine("}"); + AddDeprecatedFlag(writer); + writer->WriteLine("public Builder Clear$0$() {", property_name()); + writer->WriteLine(" PrepareBuilder();"); + writer->WriteLine(" result.$0$_.Clear();", name()); + writer->WriteLine(" return this;"); + writer->WriteLine("}"); +} + +void RepeatedMessageFieldGenerator::GenerateMergingCode(Writer* writer) { + writer->WriteLine("if (other.$0$_.Count != 0) {", name()); + writer->WriteLine(" result.$0$_.Add(other.$0$_);", name()); + writer->WriteLine("}"); +} + +void RepeatedMessageFieldGenerator::GenerateBuildingCode(Writer* writer) { + writer->WriteLine("$0$_.MakeReadOnly();", name()); +} + +void RepeatedMessageFieldGenerator::GenerateParsingCode(Writer* writer) { + writer->WriteLine( + "input.Read$0$Array(tag, field_name, result.$1$_, $2$.DefaultInstance, extensionRegistry);", + message_or_group(), name(), type_name()); +} + +void RepeatedMessageFieldGenerator::GenerateSerializationCode(Writer* writer) { + writer->WriteLine("if ($0$_.Count > 0) {", name()); + writer->Indent(); + writer->WriteLine("output.Write$0$Array($1$, field_names[$3$], $2$_);", + message_or_group(), number(), name(), field_ordinal()); + writer->Outdent(); + writer->WriteLine("}"); +} + +void RepeatedMessageFieldGenerator::GenerateSerializedSizeCode(Writer* writer) { + writer->WriteLine("foreach ($0$ element in $1$List) {", type_name(), + property_name()); + writer->WriteLine( + " size += pb::CodedOutputStream.Compute$0$Size($1$, element);", + message_or_group(), number()); + writer->WriteLine("}"); +} + +void RepeatedMessageFieldGenerator::WriteHash(Writer* writer) { + writer->WriteLine("foreach($0$ i in $1$_)", type_name(), name()); + writer->WriteLine(" hash ^= i.GetHashCode();"); +} +void RepeatedMessageFieldGenerator::WriteEquals(Writer* writer) { + writer->WriteLine("if($0$_.Count != other.$0$_.Count) return false;", name()); + writer->WriteLine("for(int ix=0; ix < $0$_.Count; ix++)", name()); + writer->WriteLine(" if(!$0$_[ix].Equals(other.$0$_[ix])) return false;", + name()); +} +void RepeatedMessageFieldGenerator::WriteToString(Writer* writer) { + writer->WriteLine("PrintField(\"$0$\", $1$_, writer);", + GetFieldName(descriptor_), name()); +} + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h new file mode 100644 index 00000000..104274cb --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.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_CSHARP_REPEATED_MESSAGE_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_MESSAGE_FIELD_H__ + +#include <string> + +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/compiler/csharp/csharp_field_base.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +class Writer; + +class RepeatedMessageFieldGenerator : public FieldGeneratorBase { + public: + RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); + ~RepeatedMessageFieldGenerator(); + + virtual void GenerateMembers(Writer* writer); + virtual void GenerateBuilderMembers(Writer* writer); + virtual void GenerateMergingCode(Writer* writer); + virtual void GenerateBuildingCode(Writer* writer); + virtual void GenerateParsingCode(Writer* writer); + virtual void GenerateSerializationCode(Writer* writer); + virtual void GenerateSerializedSizeCode(Writer* writer); + + virtual void WriteHash(Writer* writer); + virtual void WriteEquals(Writer* writer); + virtual void WriteToString(Writer* writer); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator); +}; + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_MESSAGE_FIELD_H__ + diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc b/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc new file mode 100644 index 00000000..8b285468 --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc @@ -0,0 +1,219 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <sstream> + +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/compiler/plugin.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/wire_format.h> + +#include <google/protobuf/compiler/csharp/csharp_helpers.h> +#include <google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h> +#include <google/protobuf/compiler/csharp/csharp_writer.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator( + const FieldDescriptor* descriptor, int fieldOrdinal) + : FieldGeneratorBase(descriptor, fieldOrdinal) { +} + +RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() { + +} + +void RepeatedPrimitiveFieldGenerator::GenerateMembers(Writer* writer) { + if (descriptor_->is_packed() && optimize_speed()) { + writer->WriteLine("private int $0$MemoizedSerializedSize;", name()); + } + writer->WriteLine( + "private pbc::PopsicleList<$0$> $1$_ = new pbc::PopsicleList<$0$>();", + type_name(), name()); + AddPublicMemberAttributes(writer); + writer->WriteLine("public scg::IList<$0$> $1$List {", type_name(), + property_name()); + writer->WriteLine(" get { return pbc::Lists.AsReadOnly($0$_); }", name()); + writer->WriteLine("}"); + + // TODO(jonskeet): Redundant API calls? Possibly - include for portability though. Maybe create an option. + AddDeprecatedFlag(writer); + writer->WriteLine("public int $0$Count {", property_name()); + writer->WriteLine(" get { return $0$_.Count; }", name()); + writer->WriteLine("}"); + + AddPublicMemberAttributes(writer); + writer->WriteLine("public $0$ Get$1$(int index) {", type_name(), + property_name()); + writer->WriteLine(" return $0$_[index];", name()); + writer->WriteLine("}"); +} + +void RepeatedPrimitiveFieldGenerator::GenerateBuilderMembers(Writer* writer) { + // Note: We can return the original list here, because we make it unmodifiable when we build + // We return it via IPopsicleList so that collection initializers work more pleasantly. + AddPublicMemberAttributes(writer); + writer->WriteLine("public pbc::IPopsicleList<$0$> $1$List {", type_name(), + property_name()); + writer->WriteLine(" get { return PrepareBuilder().$0$_; }", name()); + writer->WriteLine("}"); + AddDeprecatedFlag(writer); + writer->WriteLine("public int $0$Count {", property_name()); + writer->WriteLine(" get { return result.$0$Count; }", property_name()); + writer->WriteLine("}"); + AddPublicMemberAttributes(writer); + writer->WriteLine("public $0$ Get$1$(int index) {", type_name(), + property_name()); + writer->WriteLine(" return result.Get$0$(index);", property_name()); + writer->WriteLine("}"); + AddPublicMemberAttributes(writer); + writer->WriteLine("public Builder Set$0$(int index, $1$ value) {", + property_name(), type_name()); + AddNullCheck(writer); + writer->WriteLine(" PrepareBuilder();"); + writer->WriteLine(" result.$0$_[index] = value;", name()); + writer->WriteLine(" return this;"); + writer->WriteLine("}"); + AddPublicMemberAttributes(writer); + writer->WriteLine("public Builder Add$0$($1$ value) {", property_name(), + type_name()); + AddNullCheck(writer); + writer->WriteLine(" PrepareBuilder();"); + writer->WriteLine(" result.$0$_.Add(value);", name(), type_name()); + writer->WriteLine(" return this;"); + writer->WriteLine("}"); + AddPublicMemberAttributes(writer); + writer->WriteLine( + "public Builder AddRange$0$(scg::IEnumerable<$1$> values) {", + property_name(), type_name()); + writer->WriteLine(" PrepareBuilder();"); + writer->WriteLine(" result.$0$_.Add(values);", name()); + writer->WriteLine(" return this;"); + writer->WriteLine("}"); + AddDeprecatedFlag(writer); + writer->WriteLine("public Builder Clear$0$() {", property_name()); + writer->WriteLine(" PrepareBuilder();"); + writer->WriteLine(" result.$0$_.Clear();", name()); + writer->WriteLine(" return this;"); + writer->WriteLine("}"); +} + +void RepeatedPrimitiveFieldGenerator::GenerateMergingCode(Writer* writer) { + writer->WriteLine("if (other.$0$_.Count != 0) {", name()); + writer->WriteLine(" result.$0$_.Add(other.$0$_);", name()); + writer->WriteLine("}"); +} + +void RepeatedPrimitiveFieldGenerator::GenerateBuildingCode(Writer* writer) { + writer->WriteLine("$0$_.MakeReadOnly();", name()); +} + +void RepeatedPrimitiveFieldGenerator::GenerateParsingCode(Writer* writer) { + writer->WriteLine("input.Read$0$Array(tag, field_name, result.$1$_);", + capitalized_type_name(), name()); +} + +void RepeatedPrimitiveFieldGenerator::GenerateSerializationCode( + Writer* writer) { + writer->WriteLine("if ($0$_.Count > 0) {", name()); + writer->Indent(); + if (descriptor_->is_packed()) { + writer->WriteLine( + "output.WritePacked$0$Array($1$, field_names[$3$], $2$MemoizedSerializedSize, $2$_);", + capitalized_type_name(), number(), name(), field_ordinal()); + } else { + writer->WriteLine("output.Write$0$Array($1$, field_names[$3$], $2$_);", + capitalized_type_name(), number(), name(), + field_ordinal()); + } + writer->Outdent(); + writer->WriteLine("}"); +} + +void RepeatedPrimitiveFieldGenerator::GenerateSerializedSizeCode( + Writer* writer) { + writer->WriteLine("{"); + writer->Indent(); + writer->WriteLine("int dataSize = 0;"); + int fixedSize = GetFixedSize(descriptor_->type()); + if (fixedSize == -1) { + writer->WriteLine("foreach ($0$ element in $1$List) {", type_name(), + property_name()); + writer->WriteLine( + " dataSize += pb::CodedOutputStream.Compute$0$SizeNoTag(element);", + capitalized_type_name(), number()); + writer->WriteLine("}"); + } else { + writer->WriteLine("dataSize = $0$ * $1$_.Count;", SimpleItoa(fixedSize), name()); + } + writer->WriteLine("size += dataSize;"); + int tagSize = internal::WireFormat::TagSize(descriptor_->number(), descriptor_->type()); + if (descriptor_->is_packed()) { + writer->WriteLine("if ($0$_.Count != 0) {", name()); + writer->WriteLine( + " size += $0$ + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize);", + SimpleItoa(tagSize)); + writer->WriteLine("}"); + } else { + writer->WriteLine("size += $0$ * $1$_.Count;", SimpleItoa(tagSize), name()); + } + // cache the data size for packed fields. + if (descriptor_->is_packed()) { + writer->WriteLine("$0$MemoizedSerializedSize = dataSize;", name()); + } + writer->Outdent(); + writer->WriteLine("}"); +} + +void RepeatedPrimitiveFieldGenerator::WriteHash(Writer* writer) { + writer->WriteLine("foreach($0$ i in $1$_)", type_name(), name()); + writer->WriteLine(" hash ^= i.GetHashCode();"); +} +void RepeatedPrimitiveFieldGenerator::WriteEquals(Writer* writer) { + writer->WriteLine("if($0$_.Count != other.$0$_.Count) return false;", name()); + writer->WriteLine("for(int ix=0; ix < $0$_.Count; ix++)", name()); + writer->WriteLine(" if(!$0$_[ix].Equals(other.$0$_[ix])) return false;", + name()); +} +void RepeatedPrimitiveFieldGenerator::WriteToString(Writer* writer) { + writer->WriteLine("PrintField(\"$0$\", $1$_, writer);", descriptor_->name(), + name()); +} + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h b/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h new file mode 100644 index 00000000..07b12015 --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.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_CSHARP_REPEATED_PRIMITIVE_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_PRIMITIVE_FIELD_H__ + +#include <string> + +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/compiler/csharp/csharp_field_base.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +class Writer; + +class RepeatedPrimitiveFieldGenerator : public FieldGeneratorBase { + public: + RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); + ~RepeatedPrimitiveFieldGenerator(); + + virtual void GenerateMembers(Writer* writer); + virtual void GenerateBuilderMembers(Writer* writer); + virtual void GenerateMergingCode(Writer* writer); + virtual void GenerateBuildingCode(Writer* writer); + virtual void GenerateParsingCode(Writer* writer); + virtual void GenerateSerializationCode(Writer* writer); + virtual void GenerateSerializedSizeCode(Writer* writer); + + virtual void WriteHash(Writer* writer); + virtual void WriteEquals(Writer* writer); + virtual void WriteToString(Writer* writer); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPrimitiveFieldGenerator); +}; + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_PRIMITIVE_FIELD_H__ + diff --git a/src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc b/src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc new file mode 100644 index 00000000..8dfb41d4 --- /dev/null +++ b/src/google/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 <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/compiler/plugin.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/io/zero_copy_stream.h> + +#include <google/protobuf/compiler/csharp/csharp_source_generator_base.h> +#include <google/protobuf/compiler/csharp/csharp_helpers.h> +#include <google/protobuf/compiler/csharp/csharp_writer.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +SourceGeneratorBase::SourceGeneratorBase(const FileDescriptor* descriptor) + : descriptor_(descriptor) { + optimizeSize_ = (descriptor->options().optimize_for() + == FileOptions::CODE_SIZE); + optimizeSpeed_ = (descriptor->options().optimize_for() == FileOptions::SPEED); + useLiteRuntime_ = (descriptor->options().optimize_for() + == FileOptions::LITE_RUNTIME); + + optimizeSpeed_ |= useLiteRuntime_; + runtimeSuffix_ = useLiteRuntime_ ? "Lite" : ""; +} + +SourceGeneratorBase::~SourceGeneratorBase() { +} + +void SourceGeneratorBase::WriteGeneratedCodeAttributes(Writer* writer) { + // This hook can be used to reintroduce generated code attributes in the future. +} + +std::string SourceGeneratorBase::class_access_level() { + return "public"; // public_classes is always on. +} + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/csharp/csharp_source_generator_base.h b/src/google/protobuf/compiler/csharp/csharp_source_generator_base.h new file mode 100644 index 00000000..1955394e --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_source_generator_base.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_SOURCE_GENERATOR_BASE_H__ +#define GOOGLE_PROTOBUF_COMPILER_CSHARP_SOURCE_GENERATOR_BASE_H__ + +#include <string> + +#include <google/protobuf/compiler/code_generator.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +class Writer; + +class SourceGeneratorBase { + protected: + SourceGeneratorBase(const FileDescriptor* descriptor); + virtual ~SourceGeneratorBase(); + + std::string class_access_level(); + + bool optimize_size() { + return optimizeSize_; + } + bool optimize_speed() { + return optimizeSpeed_; + } + bool use_lite_runtime() { + return useLiteRuntime_; + } + std::string runtime_suffix() { + return runtimeSuffix_; + } + + void WriteGeneratedCodeAttributes(Writer* writer); + + private: + const FileDescriptor* descriptor_; + bool optimizeSize_; + bool optimizeSpeed_; + bool useLiteRuntime_; + std::string runtimeSuffix_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SourceGeneratorBase); +}; + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_SOURCE_GENERATOR_BASE_H__ + diff --git a/src/google/protobuf/compiler/csharp/csharp_umbrella_class.cc b/src/google/protobuf/compiler/csharp/csharp_umbrella_class.cc new file mode 100644 index 00000000..358cfa4f --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_umbrella_class.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 <sstream> + +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/compiler/plugin.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/io/zero_copy_stream.h> + +#include <google/protobuf/compiler/csharp/csharp_umbrella_class.h> +#include <google/protobuf/compiler/csharp/csharp_enum.h> +#include <google/protobuf/compiler/csharp/csharp_extension.h> +#include <google/protobuf/compiler/csharp/csharp_helpers.h> +#include <google/protobuf/compiler/csharp/csharp_message.h> +#include <google/protobuf/compiler/csharp/csharp_writer.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +UmbrellaClassGenerator::UmbrellaClassGenerator(const FileDescriptor* file) + : SourceGeneratorBase(file), + file_(file) { + namespace_ = GetFileNamespace(file); + umbrellaClassname_ = GetFileUmbrellaClassname(file); + umbrellaNamespace_ = GetFileUmbrellaNamespace(file); +} + +UmbrellaClassGenerator::~UmbrellaClassGenerator() { +} + +void UmbrellaClassGenerator::Generate(Writer* writer) { + WriteIntroduction(writer); + WriteExtensionRegistration(writer); + + // write children: Extensions + if (file_->extension_count() > 0) { + writer->WriteLine("#region Extensions"); + for (int i = 0; i < file_->extension_count(); i++) { + ExtensionGenerator extensionGenerator(file_->extension(i)); + extensionGenerator.Generate(writer); + } + writer->WriteLine("#endregion"); + writer->WriteLine(); + } + + writer->WriteLine("#region Static variables"); + for (int i = 0; i < file_->message_type_count(); i++) { + MessageGenerator messageGenerator(file_->message_type(i)); + messageGenerator.GenerateStaticVariables(writer); + } + writer->WriteLine("#endregion"); + if (!use_lite_runtime()) { + WriteDescriptor(writer); + } else { + WriteLiteExtensions(writer); + } + // Close the class declaration. + writer->Outdent(); + writer->WriteLine("}"); + + // Close the namespace around the umbrella class if defined + if (!umbrellaNamespace_.empty()) { + writer->Outdent(); + writer->WriteLine("}"); + } + + // write children: Enums + if (file_->enum_type_count() > 0) { + writer->WriteLine("#region Enums"); + for (int i = 0; i < file_->enum_type_count(); i++) { + EnumGenerator enumGenerator(file_->enum_type(i)); + enumGenerator.Generate(writer); + } + writer->WriteLine("#endregion"); + writer->WriteLine(); + } + + // write children: Messages + if (file_->message_type_count() > 0) { + writer->WriteLine("#region Messages"); + for (int i = 0; i < file_->message_type_count(); i++) { + MessageGenerator messageGenerator(file_->message_type(i)); + messageGenerator.Generate(writer); + } + writer->WriteLine("#endregion"); + writer->WriteLine(); + } + + // TODO(jtattermusch): add insertion point for services. + + if (!namespace_.empty()) { + writer->Outdent(); + writer->WriteLine("}"); + } + writer->WriteLine(); + writer->WriteLine("#endregion Designer generated code"); +} + +void UmbrellaClassGenerator::WriteIntroduction(Writer* writer) { + writer->WriteLine( + "// Generated by the protocol buffer compiler. DO NOT EDIT!"); + writer->WriteLine("// source: $0$", file_->name()); + writer->WriteLine("#pragma warning disable 1591, 0612, 3021"); + writer->WriteLine("#region Designer generated code"); + + writer->WriteLine(); + writer->WriteLine("using pb = global::Google.ProtocolBuffers;"); + writer->WriteLine("using pbc = global::Google.ProtocolBuffers.Collections;"); + writer->WriteLine("using pbd = global::Google.ProtocolBuffers.Descriptors;"); + writer->WriteLine("using scg = global::System.Collections.Generic;"); + + if (!namespace_.empty()) { + writer->WriteLine("namespace $0$ {", namespace_); + writer->Indent(); + writer->WriteLine(); + } + + // Add the namespace around the umbrella class if defined + if (!umbrellaNamespace_.empty()) { + writer->WriteLine("namespace $0$ {", umbrellaNamespace_); + writer->Indent(); + writer->WriteLine(); + } + + writer->WriteLine( + "[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]"); + WriteGeneratedCodeAttributes(writer); + writer->WriteLine("$0$ static partial class $1$ {", class_access_level(), + umbrellaClassname_); + writer->WriteLine(); + writer->Indent(); +} + +void UmbrellaClassGenerator::WriteExtensionRegistration(Writer* writer) { + writer->WriteLine("#region Extension registration"); + writer->WriteLine( + "public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {"); + writer->Indent(); + for (int i = 0; i < file_->extension_count(); i++) { + ExtensionGenerator extensionGenerator(file_->extension(i)); + extensionGenerator.GenerateExtensionRegistrationCode(writer); + } + for (int i = 0; i < file_->message_type_count(); i++) { + MessageGenerator messageGenerator(file_->message_type(i)); + messageGenerator.GenerateExtensionRegistrationCode(writer); + } + writer->Outdent(); + writer->WriteLine("}"); + writer->WriteLine("#endregion"); +} + +void UmbrellaClassGenerator::WriteDescriptor(Writer* writer) { + writer->WriteLine("#region Descriptor"); + + writer->WriteLine("public static pbd::FileDescriptor Descriptor {"); + writer->WriteLine(" get { return descriptor; }"); + writer->WriteLine("}"); + writer->WriteLine("private static pbd::FileDescriptor descriptor;"); + writer->WriteLine(); + writer->WriteLine("static $0$() {", umbrellaClassname_); + writer->Indent(); + writer->WriteLine( + "byte[] descriptorData = global::System.Convert.FromBase64String("); + writer->Indent(); + writer->Indent(); + writer->WriteLine("string.Concat("); + writer->Indent(); + + // TODO(jonskeet): Consider a C#-escaping format here instead of just Base64. + std::string base64 = FileDescriptorToBase64(file_); + while (base64.size() > 60) { + writer->WriteLine("\"$0$\", ", base64.substr(0, 60)); + base64 = base64.substr(60); + } + writer->Outdent(); + writer->WriteLine("\"$0$\"));", base64); + writer->Outdent(); + writer->Outdent(); + writer->WriteLine( + "pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {"); + writer->Indent(); + writer->WriteLine("descriptor = root;"); + for (int i = 0; i < file_->message_type_count(); i++) { + MessageGenerator messageGenerator(file_->message_type(i)); + messageGenerator.GenerateStaticVariableInitializers(writer); + } + for (int i = 0; i < file_->extension_count(); i++) { + ExtensionGenerator extensionGenerator(file_->extension(i)); + extensionGenerator.GenerateStaticVariableInitializers(writer); + } + + if (uses_extensions()) { + // Must construct an ExtensionRegistry containing all possible extensions + // and return it. + writer->WriteLine( + "pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance();"); + writer->WriteLine("RegisterAllExtensions(registry);"); + for (int i = 0; i < file_->dependency_count(); i++) { + writer->WriteLine("$0$.RegisterAllExtensions(registry);", + GetFullUmbrellaClassName(file_->dependency(i))); + } + writer->WriteLine("return registry;"); + } else { + writer->WriteLine("return null;"); + } + writer->Outdent(); + writer->WriteLine("};"); + + // ----------------------------------------------------------------- + // Invoke internalBuildGeneratedFileFrom() to build the file. + writer->WriteLine( + "pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,"); + writer->WriteLine(" new pbd::FileDescriptor[] {"); + for (int i = 0; i < file_->dependency_count(); i++) { + writer->WriteLine(" $0$.Descriptor, ", + GetFullUmbrellaClassName(file_->dependency(i))); + } + writer->WriteLine(" }, assigner);"); + writer->Outdent(); + writer->WriteLine("}"); + writer->WriteLine("#endregion"); + writer->WriteLine(); +} + +void UmbrellaClassGenerator::WriteLiteExtensions(Writer* writer) { + writer->WriteLine("#region Extensions"); + writer->WriteLine("internal static readonly object Descriptor;"); + writer->WriteLine("static $0$() {", umbrellaClassname_); + writer->Indent(); + writer->WriteLine("Descriptor = null;"); + for (int i = 0; i < file_->message_type_count(); i++) { + MessageGenerator messageGenerator(file_->message_type(i)); + messageGenerator.GenerateStaticVariableInitializers(writer); + } + for (int i = 0; i < file_->extension_count(); i++) { + ExtensionGenerator extensionGenerator(file_->extension(i)); + extensionGenerator.GenerateStaticVariableInitializers(writer); + } + writer->Outdent(); + writer->WriteLine("}"); + writer->WriteLine("#endregion"); + writer->WriteLine(); +} + +bool UmbrellaClassGenerator::uses_extensions() { + // TODO(jtattermusch): implement recursive descent that looks for extensions. + // For now, we conservatively assume that extensions are used. + return true; +} + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/csharp/csharp_umbrella_class.h b/src/google/protobuf/compiler/csharp/csharp_umbrella_class.h new file mode 100644 index 00000000..757f8f91 --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_umbrella_class.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_CSHARP_UMBRELLA_CLASS_H__ +#define GOOGLE_PROTOBUF_COMPILER_CSHARP_UMBRELLA_CLASS_H__ + +#include <string> + +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/compiler/csharp/csharp_source_generator_base.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +class Writer; + +class UmbrellaClassGenerator : public SourceGeneratorBase { + public: + UmbrellaClassGenerator(const FileDescriptor* file); + ~UmbrellaClassGenerator(); + + void Generate(Writer* write); + + private: + const FileDescriptor* file_; + + std::string namespace_; + std::string umbrellaClassname_; + std::string umbrellaNamespace_; + + void WriteIntroduction(Writer* writer); + void WriteExtensionRegistration(Writer* writer); + void WriteDescriptor(Writer* writer); + void WriteLiteExtensions(Writer* write); + + bool uses_extensions(); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UmbrellaClassGenerator); +}; + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_UMBRELLA_CLASS_H__ + diff --git a/src/google/protobuf/compiler/csharp/csharp_writer.cc b/src/google/protobuf/compiler/csharp/csharp_writer.cc new file mode 100644 index 00000000..2bcafde5 --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_writer.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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <algorithm> +#include <google/protobuf/stubs/hash.h> +#include <limits> +#include <vector> + +#include <google/protobuf/compiler/csharp/csharp_writer.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/substitute.h> + +#include <google/protobuf/compiler/csharp/csharp_field_base.h> +#include <google/protobuf/compiler/csharp/csharp_enum_field.h> +#include <google/protobuf/compiler/csharp/csharp_message_field.h> +#include <google/protobuf/compiler/csharp/csharp_primitive_field.h> +#include <google/protobuf/compiler/csharp/csharp_repeated_enum_field.h> +#include <google/protobuf/compiler/csharp/csharp_repeated_message_field.h> +#include <google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +Writer::Writer(google::protobuf::io::Printer* printer) + : printer_(printer), + newline_("\n") { + // TODO(jtattermusch): make newline customizable. +} + +Writer::~Writer() { +} + +void Writer::Indent() { + printer_->Indent(); +} + +void Writer::Outdent() { + printer_->Outdent(); +} + +void Writer::Write(const char* text) { + printer_->Print(text); +} + +void Writer::Write(const char* text, const string& value0) { + printer_->Print(text, "0", value0); +} + +void Writer::Write(const char* text, const string& value0, + const string& value1) { + printer_->Print(text, "0", value0, "1", value1); +} + +void Writer::Write(const char* text, const string& value0, const string& value1, + const string& value2) { + printer_->Print(text, "0", value0, "1", value1, "2", value2); +} + +void Writer::Write(const char* text, const string& value0, const string& value1, + const string& value2, const string& value3) { + printer_->Print(text, "0", value0, "1", value1, "2", value2, "3", value3); +} + +void Writer::WriteLine() { + printer_->Print(newline_); +} + +void Writer::WriteLine(const char* text) { + Write(text); + WriteLine(); +} + +void Writer::WriteLine(const char* text, const string& value0) { + Write(text, value0); + WriteLine(); +} + +void Writer::WriteLine(const char* text, const string& value0, + const string& value1) { + Write(text, value0, value1); + WriteLine(); +} + +void Writer::WriteLine(const char* text, const string& value0, + const string& value1, const string& value2) { + Write(text, value0, value1, value2); + WriteLine(); +} + +void Writer::WriteLine(const char* text, const string& value0, + const string& value1, const string& value2, + const string& value3) { + Write(text, value0, value1, value2, value3); + WriteLine(); +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/csharp/csharp_writer.h b/src/google/protobuf/compiler/csharp/csharp_writer.h new file mode 100644 index 00000000..26c59b31 --- /dev/null +++ b/src/google/protobuf/compiler/csharp/csharp_writer.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. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_WRITER_H__ +#define GOOGLE_PROTOBUF_COMPILER_CSHARP_WRITER_H__ + +#include <string> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/io/printer.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace csharp { + +// Simple wrapper around Printer that supports customizable line endings +// and number-based variables (e.g. $0$). +class Writer { + public: + Writer(io::Printer* printer); + ~Writer(); + + void Indent(); + void Outdent(); + + void Write(const char* text); + + void Write(const char* text, const string& value0); + + void Write(const char* text, const string& value0, const string& value1); + + void Write(const char* text, const string& value0, const string& value1, + const string& value2); + + void Write(const char* text, const string& value0, const string& value1, + const string& value2, const string& value3); + + void WriteLine(); + + void WriteLine(const char* text); + + void WriteLine(const char* text, const string& value0); + + void WriteLine(const char* text, const string& value0, const string& value1); + + void WriteLine(const char* text, const string& value0, const string& value1, + const string& value2); + + void WriteLine(const char* text, const string& value0, const string& value1, + const string& value2, const string& value3); + private: + io::Printer* printer_; + const char* newline_; +}; + +} // namespace csharp +} // namespace compiler +} // namespace protobuf +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_WRITER_H__ diff --git a/src/google/protobuf/compiler/java/java_enum_field.cc b/src/google/protobuf/compiler/java/java_enum_field.cc index 71a2ba4b..39318a19 100644 --- a/src/google/protobuf/compiler/java/java_enum_field.cc +++ b/src/google/protobuf/compiler/java/java_enum_field.cc @@ -67,7 +67,13 @@ void SetEnumVariables(const FieldDescriptor* descriptor, (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver); (*variables)["default_number"] = SimpleItoa( descriptor->default_value_enum()->number()); - (*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor)); + if (descriptor->is_packed()) { + (*variables)["tag"] = SimpleItoa(internal::WireFormatLite::MakeTag( + descriptor->number(), + internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED)); + } else { + (*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor)); + } (*variables)["tag_size"] = SimpleItoa( internal::WireFormat::TagSize(descriptor->number(), GetType(descriptor))); // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported @@ -641,7 +647,7 @@ GenerateMembers(io::Printer* printer) const { "}\n"); } - if (descriptor_->options().packed() && + if (descriptor_->is_packed() && HasGeneratedMethods(descriptor_->containing_type())) { printer->Print(variables_, "private int $name$MemoizedSerializedSize;\n"); @@ -884,7 +890,7 @@ GenerateParsingDoneCode(io::Printer* printer) const { void RepeatedImmutableEnumFieldGenerator:: GenerateSerializationCode(io::Printer* printer) const { - if (descriptor_->options().packed()) { + if (descriptor_->is_packed()) { printer->Print(variables_, "if (get$capitalized_name$List().size() > 0) {\n" " output.writeRawVarint32($tag$);\n" @@ -915,7 +921,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const { "}\n"); printer->Print( "size += dataSize;\n"); - if (descriptor_->options().packed()) { + if (descriptor_->is_packed()) { printer->Print(variables_, "if (!get$capitalized_name$List().isEmpty()) {" " size += $tag_size$;\n" @@ -928,7 +934,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const { } // cache the data size for packed fields. - if (descriptor_->options().packed()) { + if (descriptor_->is_packed()) { printer->Print(variables_, "$name$MemoizedSerializedSize = dataSize;\n"); } diff --git a/src/google/protobuf/compiler/java/java_enum_field_lite.cc b/src/google/protobuf/compiler/java/java_enum_field_lite.cc new file mode 100644 index 00000000..697a07a7 --- /dev/null +++ b/src/google/protobuf/compiler/java/java_enum_field_lite.cc @@ -0,0 +1,967 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: kenton@google.com (Kenton Varda) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <map> +#include <string> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/compiler/java/java_context.h> +#include <google/protobuf/compiler/java/java_doc_comment.h> +#include <google/protobuf/compiler/java/java_enum_field_lite.h> +#include <google/protobuf/compiler/java/java_helpers.h> +#include <google/protobuf/compiler/java/java_name_resolver.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/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, + map<string, string>* variables) { + SetCommonFieldVariables(descriptor, info, variables); + + (*variables)["type"] = + name_resolver->GetImmutableClassName(descriptor->enum_type()); + (*variables)["mutable_type"] = + name_resolver->GetMutableClassName(descriptor->enum_type()); + (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver); + (*variables)["default_number"] = SimpleItoa( + descriptor->default_value_enum()->number()); + (*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor)); + (*variables)["tag_size"] = SimpleItoa( + 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)["on_changed"] = + HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : ""; + + if (SupportFieldPresence(descriptor->file())) { + // 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()"; + } + + // For repeated builders, the underlying list tracks mutability state. + (*variables)["is_mutable"] = (*variables)["name"] + "_.isModifiable()"; + + (*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 + +// =================================================================== + +ImmutableEnumFieldLiteGenerator:: +ImmutableEnumFieldLiteGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex, + Context* context) + : descriptor_(descriptor), messageBitIndex_(messageBitIndex), + builderBitIndex_(builderBitIndex), + name_resolver_(context->GetNameResolver()) { + SetEnumVariables(descriptor, messageBitIndex, builderBitIndex, + context->GetFieldGeneratorInfo(descriptor), + name_resolver_, &variables_); +} + +ImmutableEnumFieldLiteGenerator::~ImmutableEnumFieldLiteGenerator() {} + +int ImmutableEnumFieldLiteGenerator::GetNumBitsForMessage() const { + return 1; +} + +int ImmutableEnumFieldLiteGenerator::GetNumBitsForBuilder() const { + return 0; +} + +void ImmutableEnumFieldLiteGenerator:: +GenerateInterfaceMembers(io::Printer* printer) const { + if (SupportFieldPresence(descriptor_->file())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$boolean has$capitalized_name$();\n"); + } + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$int get$capitalized_name$Value();\n"); + } + WriteFieldDocComment(printer, descriptor_); + 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 (SupportFieldPresence(descriptor_->file())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $get_has_field_bit_message$;\n" + "}\n"); + } + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public int get$capitalized_name$Value() {\n" + " return $name$_;\n" + "}\n"); + } + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$() {\n" + " $type$ result = $type$.valueOf($name$_);\n" + " return result == null ? $unknown$ : result;\n" + "}\n"); + + // Generate private setters for the builder to proxy into. + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void set$capitalized_name$Value(int value) {\n" + " $set_has_field_bit_message$" + " $name$_ = value;\n" + "}\n"); + } + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void set$capitalized_name$($type$ value) {\n" + " if (value == null) {\n" + " throw new NullPointerException();\n" + " }\n" + " $set_has_field_bit_message$\n" + " $name$_ = value.getNumber();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + 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 (SupportFieldPresence(descriptor_->file())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return instance.has$capitalized_name$();\n" + "}\n"); + } + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public int get$capitalized_name$Value() {\n" + " return instance.get$capitalized_name$Value();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder set$capitalized_name$Value(int value) {\n" + " copyOnWrite();\n" + " instance.set$capitalized_name$Value(int value);\n" + " return this;\n" + "}\n"); + } + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$() {\n" + " return instance.get$capitalized_name$();\n" + "}\n"); + 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"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder clear$capitalized_name$() {\n" + " copyOnWrite();\n" + " instance.clear$capitalized_name$();\n" + " return this;\n" + "}\n"); +} + +void ImmutableEnumFieldLiteGenerator:: +GenerateFieldBuilderInitializationCode(io::Printer* printer) const { + // noop for enums +} + +void ImmutableEnumFieldLiteGenerator:: +GenerateInitializationCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_ = $default_number$;\n"); +} + +void ImmutableEnumFieldLiteGenerator:: +GenerateMergingCode(io::Printer* printer) const { + if (SupportFieldPresence(descriptor_->file())) { + 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 ImmutableEnumFieldLiteGenerator:: +GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const { + // noop for scalars +} + +void ImmutableEnumFieldLiteGenerator:: +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" + "$type$ value = $type$.valueOf(rawValue);\n" + "if (value == null) {\n"); + if (PreserveUnknownFields(descriptor_->containing_type())) { + printer->Print(variables_, + " unknownFields.mergeVarintField($number$, rawValue);\n"); + } + printer->Print(variables_, + "} else {\n" + " $set_has_field_bit_message$\n" + " $name$_ = rawValue;\n" + "}\n"); + } +} + +void ImmutableEnumFieldLiteGenerator:: +GenerateParsingDoneCode(io::Printer* printer) const { + // noop for enums +} + +void ImmutableEnumFieldLiteGenerator:: +GenerateSerializationCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($is_field_present_message$) {\n" + " output.writeEnum($number$, $name$_);\n" + "}\n"); +} + +void ImmutableEnumFieldLiteGenerator:: +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 ImmutableEnumFieldLiteGenerator:: +GenerateEqualsCode(io::Printer* printer) const { + printer->Print(variables_, + "result = result && $name$_ == other.$name$_;\n"); +} + +void ImmutableEnumFieldLiteGenerator:: +GenerateHashCode(io::Printer* printer) const { + printer->Print(variables_, + "hash = (37 * hash) + $constant_name$;\n" + "hash = (53 * hash) + $name$_;\n"); +} + +string ImmutableEnumFieldLiteGenerator::GetBoxedType() const { + return name_resolver_->GetImmutableClassName(descriptor_->enum_type()); +} + +// =================================================================== + +ImmutableEnumOneofFieldLiteGenerator:: +ImmutableEnumOneofFieldLiteGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex, + Context* context) + : ImmutableEnumFieldLiteGenerator( + descriptor, messageBitIndex, builderBitIndex, 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); + if (SupportFieldPresence(descriptor_->file())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $has_oneof_case_message$;\n" + "}\n"); + } + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldDocComment(printer, descriptor_); + 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"); + } + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$() {\n" + " if ($has_oneof_case_message$) {\n" + " $type$ result = $type$.valueOf((java.lang.Integer) $oneof_name$_);\n" + " return result == null ? $unknown$ : result;\n" + " }\n" + " return $default$;\n" + "}\n"); + + // Generate private setters for the builder to proxy into. + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void set$capitalized_name$Value(int value) {\n" + " $set_oneof_case_message$;\n" + " $oneof_name$_ = value;\n" + "}\n"); + } + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void 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" + "}\n"); + 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 ImmutableEnumOneofFieldLiteGenerator:: +GenerateBuilderMembers(io::Printer* printer) const { + if (SupportFieldPresence(descriptor_->file())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return instance.has$capitalized_name$();\n" + "}\n"); + } + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public int get$capitalized_name$Value() {\n" + " return instance.get$capitalized_name$Value();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + 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"); + } + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$() {\n" + " return instance.get$capitalized_name$();\n" + "}\n"); + 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"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder clear$capitalized_name$() {\n" + " copyOnWrite();\n" + " instance.clear$capitalized_name$();\n" + " return this;\n" + "}\n"); +} + +void ImmutableEnumOneofFieldLiteGenerator:: +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 ImmutableEnumOneofFieldLiteGenerator:: +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" + "$type$ value = $type$.valueOf(rawValue);\n" + "if (value == null) {\n"); + if (PreserveUnknownFields(descriptor_->containing_type())) { + printer->Print(variables_, + " unknownFields.mergeVarintField($number$, rawValue);\n"); + } + printer->Print(variables_, + "} else {\n" + " $set_oneof_case_message$;\n" + " $oneof_name$_ = rawValue;\n" + "}\n"); + } +} + +void ImmutableEnumOneofFieldLiteGenerator:: +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 ImmutableEnumOneofFieldLiteGenerator:: +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 ImmutableEnumOneofFieldLiteGenerator:: +GenerateEqualsCode(io::Printer* printer) const { + if (SupportUnknownEnumValue(descriptor_->file())) { + printer->Print(variables_, + "result = result && get$capitalized_name$Value()\n" + " == other.get$capitalized_name$Value();\n"); + } else { + printer->Print(variables_, + "result = result && get$capitalized_name$()\n" + " .equals(other.get$capitalized_name$());\n"); + } +} + +void ImmutableEnumOneofFieldLiteGenerator:: +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"); + } +} + +// =================================================================== + +RepeatedImmutableEnumFieldLiteGenerator:: +RepeatedImmutableEnumFieldLiteGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex, + Context* context) + : descriptor_(descriptor), messageBitIndex_(messageBitIndex), + builderBitIndex_(builderBitIndex), context_(context), + name_resolver_(context->GetNameResolver()) { + SetEnumVariables(descriptor, messageBitIndex, builderBitIndex, + context->GetFieldGeneratorInfo(descriptor), + name_resolver_, &variables_); +} + +RepeatedImmutableEnumFieldLiteGenerator:: +~RepeatedImmutableEnumFieldLiteGenerator() {} + +int RepeatedImmutableEnumFieldLiteGenerator::GetNumBitsForMessage() const { + return 0; +} + +int RepeatedImmutableEnumFieldLiteGenerator::GetNumBitsForBuilder() const { + return 0; +} + +void RepeatedImmutableEnumFieldLiteGenerator:: +GenerateInterfaceMembers(io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$java.util.List<$type$> get$capitalized_name$List();\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$int get$capitalized_name$Count();\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$$type$ get$capitalized_name$(int index);\n"); + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$java.util.List<java.lang.Integer>\n" + "get$capitalized_name$ValueList();\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$int get$capitalized_name$Value(int index);\n"); + } +} + +void RepeatedImmutableEnumFieldLiteGenerator:: +GenerateMembers(io::Printer* printer) const { + printer->Print(variables_, + // TODO(dweis): Switch to IntList? + "private com.google.protobuf.Internal.ProtobufList<\n" + " 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" + " $type$ result = $type$.valueOf(from);\n" + " return result == null ? $unknown$ : result;\n" + " }\n" + " };\n"); + PrintExtraFieldInfo(variables_, printer); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$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"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public int get$capitalized_name$Count() {\n" + " return $name$_.size();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + " return $name$_converter_.convert($name$_.get(index));\n" + "}\n"); + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public java.util.List<java.lang.Integer>\n" + "get$capitalized_name$ValueList() {\n" + " return $name$_;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public int get$capitalized_name$Value(int index) {\n" + " return $name$_.get(index);\n" + "}\n"); + } + + if (descriptor_->options().packed() && + 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" + " if (!$is_mutable$) {\n" + " $name$_ = newProtobufList($name$_);\n" + " }\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void 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" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void 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" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + 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$_.add(value.getNumber());\n" + " }\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void clear$capitalized_name$() {\n" + " $name$_ = emptyProtobufList();\n" + "}\n"); + + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void set$capitalized_name$Value(\n" + " int index, int value) {\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.set(index, value);\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void add$capitalized_name$Value(int value) {\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.add(value);\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + 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$_.add(value);\n" + " }\n" + "}\n"); + } +} + +void RepeatedImmutableEnumFieldLiteGenerator:: +GenerateBuilderMembers(io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n" + " return instance.get$capitalized_name$List();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public int get$capitalized_name$Count() {\n" + " return instance.get$capitalized_name$Count();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + " return instance.get$capitalized_name$(index);\n" + "}\n"); + 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"); + 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"); + 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);" + " return this;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder clear$capitalized_name$() {\n" + " copyOnWrite();\n" + " instance.clear$capitalized_name$();\n" + " return this;\n" + "}\n"); + + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$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"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public int get$capitalized_name$Value(int index) {\n" + " return instance.get$capitalized_name$Value(index);\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + 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"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder add$capitalized_name$Value(int value) {\n" + " instance.add$capitalized_name$Value(value);\n" + " return this;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + 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"); + } +} + +void RepeatedImmutableEnumFieldLiteGenerator:: +GenerateFieldBuilderInitializationCode(io::Printer* printer) const { + // noop for enums +} + +void RepeatedImmutableEnumFieldLiteGenerator:: +GenerateInitializationCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_ = emptyProtobufList();\n"); +} + +void RepeatedImmutableEnumFieldLiteGenerator:: +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" + " } else {\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.addAll(other.$name$_);\n" + " }\n" + " $on_changed$\n" + "}\n"); +} + +void RepeatedImmutableEnumFieldLiteGenerator:: +GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const { + printer->Print(variables_, + "$name$_.makeImmutable();\n"); +} + +void RepeatedImmutableEnumFieldLiteGenerator:: +GenerateParsingCode(io::Printer* printer) const { + // Read and store the enum + if (SupportUnknownEnumValue(descriptor_->file())) { + printer->Print(variables_, + "int rawValue = input.readEnum();\n" + "if (!$is_mutable$) {\n" + " $name$_ = newProtobufList();\n" + "}\n" + "$name$_.add(rawValue);\n"); + } else { + printer->Print(variables_, + "int rawValue = input.readEnum();\n" + "$type$ value = $type$.valueOf(rawValue);\n" + "if (value == null) {\n"); + if (PreserveUnknownFields(descriptor_->containing_type())) { + printer->Print(variables_, + " unknownFields.mergeVarintField($number$, rawValue);\n"); + } + printer->Print(variables_, + "} else {\n" + " if (!$is_mutable$) {\n" + " $name$_ = newProtobufList();\n" + " }\n" + " $name$_.add(rawValue);\n" + "}\n"); + } +} + +void RepeatedImmutableEnumFieldLiteGenerator:: +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 RepeatedImmutableEnumFieldLiteGenerator:: +GenerateParsingDoneCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($is_mutable$) {\n" + " $name$_.makeImmutable();\n" + "}\n"); +} + +void RepeatedImmutableEnumFieldLiteGenerator:: +GenerateSerializationCode(io::Printer* printer) const { + if (descriptor_->options().packed()) { + printer->Print(variables_, + "if (get$capitalized_name$List().size() > 0) {\n" + " output.writeRawVarint32($tag$);\n" + " output.writeRawVarint32($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 RepeatedImmutableEnumFieldLiteGenerator:: +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_->options().packed()) { + printer->Print(variables_, + "if (!get$capitalized_name$List().isEmpty()) {" + " size += $tag_size$;\n" + " size += com.google.protobuf.CodedOutputStream\n" + " .computeRawVarint32Size(dataSize);\n" + "}"); + } else { + printer->Print(variables_, + "size += $tag_size$ * $name$_.size();\n"); + } + + // cache the data size for packed fields. + if (descriptor_->options().packed()) { + printer->Print(variables_, + "$name$MemoizedSerializedSize = dataSize;\n"); + } + + printer->Outdent(); + printer->Print("}\n"); +} + +void RepeatedImmutableEnumFieldLiteGenerator:: +GenerateEqualsCode(io::Printer* printer) const { + printer->Print(variables_, + "result = result && $name$_.equals(other.$name$_);\n"); +} + +void RepeatedImmutableEnumFieldLiteGenerator:: +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"); +} + +string RepeatedImmutableEnumFieldLiteGenerator::GetBoxedType() const { + return name_resolver_->GetImmutableClassName(descriptor_->enum_type()); +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/java/java_enum_field_lite.h b/src/google/protobuf/compiler/java/java_enum_field_lite.h new file mode 100644 index 00000000..2c41c3e4 --- /dev/null +++ b/src/google/protobuf/compiler/java/java_enum_field_lite.h @@ -0,0 +1,159 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 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 <map> +#include <string> +#include <google/protobuf/compiler/java/java_field.h> + +namespace google { +namespace protobuf { + namespace compiler { + namespace java { + class Context; // context.h + class ClassNameResolver; // name_resolver.h + } + } +} + +namespace protobuf { +namespace compiler { +namespace java { + +class ImmutableEnumFieldLiteGenerator : public ImmutableFieldLiteGenerator { + public: + explicit ImmutableEnumFieldLiteGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, + int builderBitIndex, Context* context); + ~ImmutableEnumFieldLiteGenerator(); + + // implements ImmutableFieldLiteGenerator ------------------------------------ + int GetNumBitsForMessage() const; + int GetNumBitsForBuilder() const; + void GenerateInterfaceMembers(io::Printer* printer) const; + void GenerateMembers(io::Printer* printer) const; + void GenerateBuilderMembers(io::Printer* printer) const; + void GenerateInitializationCode(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const; + void GenerateParsingCode(io::Printer* printer) const; + void GenerateParsingDoneCode(io::Printer* printer) const; + void GenerateSerializationCode(io::Printer* printer) const; + void GenerateSerializedSizeCode(io::Printer* printer) const; + void GenerateFieldBuilderInitializationCode(io::Printer* printer) const; + void GenerateEqualsCode(io::Printer* printer) const; + void GenerateHashCode(io::Printer* printer) const; + + string GetBoxedType() const; + + protected: + const FieldDescriptor* descriptor_; + map<string, string> variables_; + const int messageBitIndex_; + const int builderBitIndex_; + Context* context_; + ClassNameResolver* name_resolver_; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableEnumFieldLiteGenerator); +}; + +class ImmutableEnumOneofFieldLiteGenerator + : public ImmutableEnumFieldLiteGenerator { + public: + ImmutableEnumOneofFieldLiteGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, + int builderBitIndex, Context* context); + ~ImmutableEnumOneofFieldLiteGenerator(); + + void GenerateMembers(io::Printer* printer) const; + void GenerateBuilderMembers(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateParsingCode(io::Printer* printer) const; + void GenerateSerializationCode(io::Printer* printer) const; + void GenerateSerializedSizeCode(io::Printer* printer) const; + void GenerateEqualsCode(io::Printer* printer) const; + void GenerateHashCode(io::Printer* printer) const; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableEnumOneofFieldLiteGenerator); +}; + +class RepeatedImmutableEnumFieldLiteGenerator + : public ImmutableFieldLiteGenerator { + public: + explicit RepeatedImmutableEnumFieldLiteGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, + int builderBitIndex, Context* context); + ~RepeatedImmutableEnumFieldLiteGenerator(); + + // implements ImmutableFieldLiteGenerator ------------------------------------ + int GetNumBitsForMessage() const; + int GetNumBitsForBuilder() const; + void GenerateInterfaceMembers(io::Printer* printer) const; + void GenerateMembers(io::Printer* printer) const; + void GenerateBuilderMembers(io::Printer* printer) const; + void GenerateInitializationCode(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const; + void GenerateParsingCode(io::Printer* printer) const; + void GenerateParsingCodeFromPacked(io::Printer* printer) const; + void GenerateParsingDoneCode(io::Printer* printer) const; + void GenerateSerializationCode(io::Printer* printer) const; + void GenerateSerializedSizeCode(io::Printer* printer) const; + void GenerateFieldBuilderInitializationCode(io::Printer* printer) const; + void GenerateEqualsCode(io::Printer* printer) const; + void GenerateHashCode(io::Printer* printer) const; + + string GetBoxedType() const; + + private: + const FieldDescriptor* descriptor_; + map<string, string> variables_; + const int messageBitIndex_; + const int builderBitIndex_; + 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/src/google/protobuf/compiler/java/java_extension.cc b/src/google/protobuf/compiler/java/java_extension.cc index 27cf416b..4db7085e 100644 --- a/src/google/protobuf/compiler/java/java_extension.cc +++ b/src/google/protobuf/compiler/java/java_extension.cc @@ -181,8 +181,9 @@ void ImmutableExtensionGenerator::Generate(io::Printer* printer) { } } -void ImmutableExtensionGenerator::GenerateNonNestedInitializationCode( +int ImmutableExtensionGenerator::GenerateNonNestedInitializationCode( io::Printer* printer) { + int bytecode_estimate = 0; if (descriptor_->extension_scope() == NULL && HasDescriptorMethods(descriptor_->file())) { // Only applies to non-nested, non-lite extensions. @@ -190,15 +191,18 @@ void ImmutableExtensionGenerator::GenerateNonNestedInitializationCode( "$name$.internalInit(descriptor.getExtensions().get($index$));\n", "name", UnderscoresToCamelCase(descriptor_), "index", SimpleItoa(descriptor_->index())); + bytecode_estimate += 21; } + return bytecode_estimate; } -void ImmutableExtensionGenerator::GenerateRegistrationCode( +int ImmutableExtensionGenerator::GenerateRegistrationCode( io::Printer* printer) { printer->Print( "registry.add($scope$.$name$);\n", "scope", scope_, "name", UnderscoresToCamelCase(descriptor_)); + return 7; } } // namespace java diff --git a/src/google/protobuf/compiler/java/java_extension.h b/src/google/protobuf/compiler/java/java_extension.h index f1701fb5..bdd42263 100644 --- a/src/google/protobuf/compiler/java/java_extension.h +++ b/src/google/protobuf/compiler/java/java_extension.h @@ -67,8 +67,12 @@ class ExtensionGenerator { virtual ~ExtensionGenerator() {} virtual void Generate(io::Printer* printer) = 0; - virtual void GenerateNonNestedInitializationCode(io::Printer* printer) = 0; - virtual void GenerateRegistrationCode(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, @@ -88,8 +92,8 @@ class ImmutableExtensionGenerator : public ExtensionGenerator { virtual ~ImmutableExtensionGenerator(); virtual void Generate(io::Printer* printer); - virtual void GenerateNonNestedInitializationCode(io::Printer* printer); - virtual void GenerateRegistrationCode(io::Printer* printer); + virtual int GenerateNonNestedInitializationCode(io::Printer* printer); + virtual int GenerateRegistrationCode(io::Printer* printer); protected: const FieldDescriptor* descriptor_; diff --git a/src/google/protobuf/compiler/java/java_field.cc b/src/google/protobuf/compiler/java/java_field.cc index af9978e2..3f0fa11f 100644 --- a/src/google/protobuf/compiler/java/java_field.cc +++ b/src/google/protobuf/compiler/java/java_field.cc @@ -42,12 +42,18 @@ #include <google/protobuf/stubs/common.h> #include <google/protobuf/compiler/java/java_context.h> #include <google/protobuf/compiler/java/java_enum_field.h> +#include <google/protobuf/compiler/java/java_enum_field_lite.h> #include <google/protobuf/compiler/java/java_helpers.h> #include <google/protobuf/compiler/java/java_lazy_message_field.h> +#include <google/protobuf/compiler/java/java_lazy_message_field_lite.h> #include <google/protobuf/compiler/java/java_map_field.h> +#include <google/protobuf/compiler/java/java_map_field_lite.h> #include <google/protobuf/compiler/java/java_message_field.h> +#include <google/protobuf/compiler/java/java_message_field_lite.h> #include <google/protobuf/compiler/java/java_primitive_field.h> +#include <google/protobuf/compiler/java/java_primitive_field_lite.h> #include <google/protobuf/compiler/java/java_string_field.h> +#include <google/protobuf/compiler/java/java_string_field_lite.h> #include <google/protobuf/io/printer.h> #include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/substitute.h> @@ -133,6 +139,79 @@ ImmutableFieldGenerator* MakeImmutableGenerator( } } +ImmutableFieldLiteGenerator* MakeImmutableLiteGenerator( + 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 ImmutableMapFieldLiteGenerator( + field, messageBitIndex, builderBitIndex, context); + } else { + if (IsLazy(field)) { + return new RepeatedImmutableLazyMessageFieldLiteGenerator( + field, messageBitIndex, builderBitIndex, context); + } else { + return new RepeatedImmutableMessageFieldLiteGenerator( + field, messageBitIndex, builderBitIndex, context); + } + } + case JAVATYPE_ENUM: + return new RepeatedImmutableEnumFieldLiteGenerator( + field, messageBitIndex, builderBitIndex, context); + case JAVATYPE_STRING: + return new RepeatedImmutableStringFieldLiteGenerator( + field, messageBitIndex, builderBitIndex, context); + default: + return new RepeatedImmutablePrimitiveFieldLiteGenerator( + field, messageBitIndex, builderBitIndex, context); + } + } else { + if (field->containing_oneof()) { + switch (GetJavaType(field)) { + case JAVATYPE_MESSAGE: + if (IsLazy(field)) { + return new ImmutableLazyMessageOneofFieldLiteGenerator( + field, messageBitIndex, builderBitIndex, context); + } else { + return new ImmutableMessageOneofFieldLiteGenerator( + field, messageBitIndex, builderBitIndex, context); + } + case JAVATYPE_ENUM: + return new ImmutableEnumOneofFieldLiteGenerator( + field, messageBitIndex, builderBitIndex, context); + case JAVATYPE_STRING: + return new ImmutableStringOneofFieldLiteGenerator( + field, messageBitIndex, builderBitIndex, context); + default: + return new ImmutablePrimitiveOneofFieldLiteGenerator( + field, messageBitIndex, builderBitIndex, context); + } + } else { + switch (GetJavaType(field)) { + case JAVATYPE_MESSAGE: + if (IsLazy(field)) { + return new ImmutableLazyMessageFieldLiteGenerator( + field, messageBitIndex, builderBitIndex, context); + } else { + return new ImmutableMessageFieldLiteGenerator( + field, messageBitIndex, builderBitIndex, context); + } + case JAVATYPE_ENUM: + return new ImmutableEnumFieldLiteGenerator( + field, messageBitIndex, builderBitIndex, context); + case JAVATYPE_STRING: + return new ImmutableStringFieldLiteGenerator( + field, messageBitIndex, builderBitIndex, context); + default: + return new ImmutablePrimitiveFieldLiteGenerator( + field, messageBitIndex, builderBitIndex, context); + } + } + } +} + static inline void ReportUnexpectedPackedFieldsCall(io::Printer* printer) { // Reaching here indicates a bug. Cases are: @@ -153,6 +232,13 @@ GenerateParsingCodeFromPacked(io::Printer* printer) const { ReportUnexpectedPackedFieldsCall(printer); } +ImmutableFieldLiteGenerator::~ImmutableFieldLiteGenerator() {} + +void ImmutableFieldLiteGenerator:: +GenerateParsingCodeFromPacked(io::Printer* printer) const { + ReportUnexpectedPackedFieldsCall(printer); +} + // =================================================================== template <> @@ -178,6 +264,28 @@ FieldGeneratorMap<ImmutableFieldGenerator>::FieldGeneratorMap( template<> FieldGeneratorMap<ImmutableFieldGenerator>::~FieldGeneratorMap() {} +template <> +FieldGeneratorMap<ImmutableFieldLiteGenerator>::FieldGeneratorMap( + const Descriptor* descriptor, Context* context) + : descriptor_(descriptor), + field_generators_(new google::protobuf::scoped_ptr< + ImmutableFieldLiteGenerator>[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++) { + ImmutableFieldLiteGenerator* generator = MakeImmutableLiteGenerator( + descriptor->field(i), messageBitIndex, builderBitIndex, context); + field_generators_[i].reset(generator); + messageBitIndex += generator->GetNumBitsForMessage(); + builderBitIndex += generator->GetNumBitsForBuilder(); + } +} + +template<> +FieldGeneratorMap<ImmutableFieldLiteGenerator>::~FieldGeneratorMap() {} + void SetCommonFieldVariables(const FieldDescriptor* descriptor, const FieldGeneratorInfo* info, diff --git a/src/google/protobuf/compiler/java/java_field.h b/src/google/protobuf/compiler/java/java_field.h index 1cf360c1..00f3c601 100644 --- a/src/google/protobuf/compiler/java/java_field.h +++ b/src/google/protobuf/compiler/java/java_field.h @@ -83,7 +83,6 @@ class ImmutableFieldGenerator { virtual void GenerateSerializedSizeCode(io::Printer* printer) const = 0; virtual void GenerateFieldBuilderInitializationCode(io::Printer* printer) const = 0; - virtual void GenerateStaticInitializationCode(io::Printer* printer) const {} virtual void GenerateEqualsCode(io::Printer* printer) const = 0; virtual void GenerateHashCode(io::Printer* printer) const = 0; @@ -94,6 +93,37 @@ class ImmutableFieldGenerator { GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableFieldGenerator); }; +class ImmutableFieldLiteGenerator { + public: + ImmutableFieldLiteGenerator() {} + virtual ~ImmutableFieldLiteGenerator(); + + 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 GenerateMergingCode(io::Printer* printer) const = 0; + virtual void GenerateDynamicMethodMakeImmutableCode(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 GenerateEqualsCode(io::Printer* printer) const = 0; + virtual void GenerateHashCode(io::Printer* printer) const = 0; + + virtual string GetBoxedType() const = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableFieldLiteGenerator); +}; + // Convenience class which constructs FieldGenerators for a Descriptor. template<typename FieldGeneratorType> diff --git a/src/google/protobuf/compiler/java/java_file.cc b/src/google/protobuf/compiler/java/java_file.cc index f1e3cf67..68b47ee1 100644 --- a/src/google/protobuf/compiler/java/java_file.cc +++ b/src/google/protobuf/compiler/java/java_file.cc @@ -38,6 +38,7 @@ #ifndef _SHARED_PTR_H #include <google/protobuf/stubs/shared_ptr.h> #endif +#include <set> #include <google/protobuf/compiler/java/java_context.h> #include <google/protobuf/compiler/java/java_enum.h> @@ -62,6 +63,19 @@ namespace java { namespace { +struct FieldDescriptorCompare { + bool operator ()(const FieldDescriptor* f1, const FieldDescriptor* f2) { + 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 @@ -69,7 +83,7 @@ namespace { // 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, - vector<const FieldDescriptor*>* extensions) { + FieldDescriptorSet* extensions) { const Reflection* reflection = message.GetReflection(); // There are unknown fields that could be extensions, thus this call fails. @@ -79,7 +93,7 @@ bool CollectExtensions(const Message& message, reflection->ListFields(message, &fields); for (int i = 0; i < fields.size(); i++) { - if (fields[i]->is_extension()) extensions->push_back(fields[i]); + if (fields[i]->is_extension()) extensions->insert(fields[i]); if (GetJavaType(fields[i]) == JAVATYPE_MESSAGE) { if (fields[i]->is_repeated()) { @@ -106,7 +120,7 @@ bool CollectExtensions(const Message& message, // in order to handle this case. void CollectExtensions(const FileDescriptorProto& file_proto, const DescriptorPool& alternate_pool, - vector<const FieldDescriptor*>* extensions, + FieldDescriptorSet* extensions, const string& file_data) { if (!CollectExtensions(file_proto, extensions)) { // There are unknown fields in the file_proto, which are probably @@ -139,6 +153,42 @@ void CollectExtensions(const FileDescriptorProto& file_proto, } } +// Compare two field descriptors, returning true if the first should come +// before the second. +bool CompareFieldsByName(const FieldDescriptor *a, const FieldDescriptor *b) { + return a->full_name() < b->full_name(); +} + +// 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 = 1<<15; // aka 32K + + if ((*bytecode_estimate) > bytesPerMethod) { + ++(*method_num); + printer->Print(chain_statement, "method_num", SimpleItoa(*method_num)); + printer->Outdent(); + printer->Print("}\n"); + printer->Print(method_decl, "method_num", SimpleItoa(*method_num)); + printer->Indent(); + *bytecode_estimate = 0; + } +} + } // namespace @@ -270,9 +320,16 @@ void FileGenerator::Generate(io::Printer* printer) { printer->Print( "static {\n"); printer->Indent(); + int bytecode_estimate = 0; + int method_num = 0; for (int i = 0; i < file_->message_type_count(); i++) { - message_generators_[i]->GenerateStaticVariableInitializers(printer); + 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(); @@ -303,12 +360,24 @@ void FileGenerator::GenerateDescriptorInitializationCodeForImmutable( SharedCodeGenerator shared_code_generator(file_); shared_code_generator.GenerateDescriptors(printer); + int bytecode_estimate = 0; + int method_num = 0; for (int i = 0; i < file_->message_type_count(); i++) { - message_generators_[i]->GenerateStaticVariableInitializers(printer); + 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++) { - extension_generators_[i]->GenerateNonNestedInitializationCode(printer); + 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 @@ -330,7 +399,7 @@ void FileGenerator::GenerateDescriptorInitializationCodeForImmutable( file_->CopyTo(&file_proto); string file_data; file_proto.SerializeToString(&file_data); - vector<const FieldDescriptor*> extensions; + FieldDescriptorSet extensions; CollectExtensions(file_proto, *file_->pool(), &extensions, file_data); if (extensions.size() > 0) { @@ -339,10 +408,17 @@ void FileGenerator::GenerateDescriptorInitializationCodeForImmutable( printer->Print( "com.google.protobuf.ExtensionRegistry registry =\n" " com.google.protobuf.ExtensionRegistry.newInstance();\n"); - for (int i = 0; i < extensions.size(); i++) { + FieldDescriptorSet::iterator it; + for (it = extensions.begin(); it != extensions.end(); it++) { google::protobuf::scoped_ptr<ExtensionGenerator> generator( - generator_factory_->NewExtensionGenerator(extensions[i])); - generator->GenerateRegistrationCode(printer); + 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" @@ -394,7 +470,7 @@ void FileGenerator::GenerateDescriptorInitializationCodeForMutable(io::Printer* file_->CopyTo(&file_proto); string file_data; file_proto.SerializeToString(&file_data); - vector<const FieldDescriptor*> extensions; + FieldDescriptorSet extensions; CollectExtensions(file_proto, *file_->pool(), &extensions, file_data); if (extensions.size() > 0) { diff --git a/src/google/protobuf/compiler/java/java_generator_factory.cc b/src/google/protobuf/compiler/java/java_generator_factory.cc index 2d1437f0..92ef851b 100644 --- a/src/google/protobuf/compiler/java/java_generator_factory.cc +++ b/src/google/protobuf/compiler/java/java_generator_factory.cc @@ -38,6 +38,7 @@ #include <google/protobuf/compiler/java/java_field.h> #include <google/protobuf/compiler/java/java_helpers.h> #include <google/protobuf/compiler/java/java_message.h> +#include <google/protobuf/compiler/java/java_message_lite.h> #include <google/protobuf/compiler/java/java_service.h> namespace google { @@ -57,7 +58,12 @@ ImmutableGeneratorFactory::~ImmutableGeneratorFactory() {} MessageGenerator* ImmutableGeneratorFactory::NewMessageGenerator( const Descriptor* descriptor) const { - return new ImmutableMessageGenerator(descriptor, context_); + if (descriptor->file()->options().optimize_for() == + FileOptions::LITE_RUNTIME) { + return new ImmutableMessageLiteGenerator(descriptor, context_); + } else { + return new ImmutableMessageGenerator(descriptor, context_); + } } ExtensionGenerator* ImmutableGeneratorFactory::NewExtensionGenerator( diff --git a/src/google/protobuf/compiler/java/java_helpers.h b/src/google/protobuf/compiler/java/java_helpers.h index 62efbefa..96d2545f 100644 --- a/src/google/protobuf/compiler/java/java_helpers.h +++ b/src/google/protobuf/compiler/java/java_helpers.h @@ -196,12 +196,6 @@ inline bool HasDescriptorMethods(const FileDescriptor* descriptor) { FileOptions::LITE_RUNTIME; } -inline bool HasNestedBuilders(const Descriptor* descriptor) { - // The proto-lite version doesn't support nested builders. - return descriptor->file()->options().optimize_for() != - FileOptions::LITE_RUNTIME; -} - // Should we generate generic services for this file? inline bool HasGenericServices(const FileDescriptor *file) { return file->service_count() > 0 && @@ -330,6 +324,10 @@ inline bool IsMapEntry(const Descriptor* descriptor) { return descriptor->options().map_entry(); } +inline bool IsMapField(const FieldDescriptor* descriptor) { + return descriptor->is_map(); +} + inline bool PreserveUnknownFields(const Descriptor* descriptor) { return descriptor->file()->syntax() != FileDescriptor::SYNTAX_PROTO3; } diff --git a/src/google/protobuf/compiler/java/java_lazy_message_field.cc b/src/google/protobuf/compiler/java/java_lazy_message_field.cc index 6e29a40b..0de8cbe5 100644 --- a/src/google/protobuf/compiler/java/java_lazy_message_field.cc +++ b/src/google/protobuf/compiler/java/java_lazy_message_field.cc @@ -72,14 +72,12 @@ GenerateMembers(io::Printer* printer) const { printer->Print(variables_, "$deprecation$public $type$ get$capitalized_name$() {\n" " return ($type$) $name$_.getValue($type$.getDefaultInstance());\n" - "}\n"); - if (HasNestedBuilders(descriptor_->containing_type())) { - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n" - " return $name$_;\n" - "}\n"); - } + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder() {\n" + " return $name$_;\n" + "}\n"); } void ImmutableLazyMessageFieldGenerator:: @@ -92,14 +90,12 @@ GenerateBuilderMembers(io::Printer* printer) const { "private com.google.protobuf.LazyFieldLite $name$_ =\n" " new com.google.protobuf.LazyFieldLite();\n"); - if (HasNestedBuilders(descriptor_->containing_type())) { - printer->Print(variables_, - // If this builder is non-null, it is used and the other fields are - // ignored. - "private com.google.protobuf.SingleFieldBuilder<\n" - " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;" - "\n"); - } + printer->Print(variables_, + // If this builder is non-null, it is used and the other fields are + // ignored. + "private com.google.protobuf.SingleFieldBuilder<\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". @@ -179,39 +175,37 @@ GenerateBuilderMembers(io::Printer* printer) const { "$clear_has_field_bit_builder$;\n" "return this;\n"); - if (HasNestedBuilders(descriptor_->containing_type())) { - 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"); - 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$_;\n" - " }\n" - "}\n"); - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "private com.google.protobuf.SingleFieldBuilder<\n" - " $type$, $type$.Builder, $type$OrBuilder> \n" - " get$capitalized_name$FieldBuilder() {\n" - " if ($name$Builder_ == null) {\n" - " $name$Builder_ = new com.google.protobuf.SingleFieldBuilder<\n" - " $type$, $type$.Builder, $type$OrBuilder>(\n" - " $name$_,\n" - " getParentForChildren(),\n" - " isClean());\n" - " $name$_ = null;\n" - " }\n" - " return $name$Builder_;\n" - "}\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"); + 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$_;\n" + " }\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private com.google.protobuf.SingleFieldBuilder<\n" + " $type$, $type$.Builder, $type$OrBuilder> \n" + " get$capitalized_name$FieldBuilder() {\n" + " if ($name$Builder_ == null) {\n" + " $name$Builder_ = new com.google.protobuf.SingleFieldBuilder<\n" + " $type$, $type$.Builder, $type$OrBuilder>(\n" + " $name$_,\n" + " getParentForChildren(),\n" + " isClean());\n" + " $name$_ = null;\n" + " }\n" + " return $name$Builder_;\n" + "}\n"); } @@ -538,14 +532,12 @@ GenerateBuilderMembers(io::Printer* printer) const { "}\n" "\n"); - if (HasNestedBuilders(descriptor_->containing_type())) { - printer->Print(variables_, - // If this builder is non-null, it is used and the other fields are - // ignored. - "private com.google.protobuf.RepeatedFieldBuilder<\n" - " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;\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<\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". @@ -723,70 +715,68 @@ GenerateBuilderMembers(io::Printer* printer) const { "return this;\n"); - if (HasNestedBuilders(descriptor_->containing_type())) { - 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"); + 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"); - 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"); + 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"); - 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"); + 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"); - 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"); - 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"); - 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<\n" - " $type$, $type$.Builder, $type$OrBuilder> \n" - " get$capitalized_name$FieldBuilder() {\n" - " if ($name$Builder_ == null) {\n" - " $name$Builder_ = new com.google.protobuf.RepeatedFieldBuilder<\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"); - } + 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"); + 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"); + 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<\n" + " $type$, $type$.Builder, $type$OrBuilder> \n" + " get$capitalized_name$FieldBuilder() {\n" + " if ($name$Builder_ == null) {\n" + " $name$Builder_ = new com.google.protobuf.RepeatedFieldBuilder<\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"); } void RepeatedImmutableLazyMessageFieldGenerator:: diff --git a/src/google/protobuf/compiler/java/java_lazy_message_field_lite.cc b/src/google/protobuf/compiler/java/java_lazy_message_field_lite.cc new file mode 100644 index 00000000..283ba1d3 --- /dev/null +++ b/src/google/protobuf/compiler/java/java_lazy_message_field_lite.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: niwasaki@google.com (Naoki Iwasaki) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <google/protobuf/compiler/java/java_context.h> +#include <google/protobuf/compiler/java/java_lazy_message_field_lite.h> +#include <google/protobuf/compiler/java/java_doc_comment.h> +#include <google/protobuf/compiler/java/java_helpers.h> +#include <google/protobuf/io/printer.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +ImmutableLazyMessageFieldLiteGenerator:: +ImmutableLazyMessageFieldLiteGenerator( + const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex, + Context* context) + : ImmutableMessageFieldLiteGenerator( + descriptor, messageBitIndex, builderBitIndex, context) { +} + +ImmutableLazyMessageFieldLiteGenerator:: +~ImmutableLazyMessageFieldLiteGenerator() {} + +void ImmutableLazyMessageFieldLiteGenerator:: +GenerateMembers(io::Printer* printer) const { + printer->Print(variables_, + "private com.google.protobuf.LazyFieldLite $name$_ =\n" + " new com.google.protobuf.LazyFieldLite();\n"); + + PrintExtraFieldInfo(variables_, printer); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $get_has_field_bit_message$;\n" + "}\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$() {\n" + " return ($type$) $name$_.getValue($type$.getDefaultInstance());\n" + "}\n"); + + // Field.Builder setField(Field value) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void set$capitalized_name$($type$ value) {\n" + " if (value == null) {\n" + " throw new NullPointerException();\n" + " }\n" + " $name$_.setValue(value);\n" + " $set_has_field_bit_message$;\n" + "}\n"); + + // Field.Builder setField(Field.Builder builderForValue) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void set$capitalized_name$(\n" + " $type$.Builder builderForValue) {\n" + " $name$_.setValue(builderForValue.build());\n" + " $set_has_field_bit_message$;\n" + "}\n"); + + // Field.Builder mergeField(Field value) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void merge$capitalized_name$($type$ value) {\n" + " if ($get_has_field_bit_message$ &&\n" + " !$name$_.containsDefaultInstance()) {\n" + " $name$_.setValue(\n" + " $type$.newBuilder(\n" + " get$capitalized_name$()).mergeFrom(value).buildPartial());\n" + " } else {\n" + " $name$_.setValue(value);\n" + " }\n" + " $set_has_field_bit_message$;\n" + "}\n"); + + // Field.Builder clearField() + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void clear$capitalized_name$() {\n" + " $name$_.clear();\n" + " $clear_has_field_bit_message$;\n" + "}\n"); +} + +void ImmutableLazyMessageFieldLiteGenerator:: +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_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return instance.has$capitalized_name$();\n" + "}\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$() {\n" + " return instance.get$capitalized_name$();\n" + "}\n"); + + // 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"); + + // 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);\n" + " return this;\n" + "}\n"); + + // 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"); + + // 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"); +} + + +void ImmutableLazyMessageFieldLiteGenerator:: +GenerateInitializationCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_.clear();\n"); +} + +void ImmutableLazyMessageFieldLiteGenerator:: +GenerateMergingCode(io::Printer* printer) const { + printer->Print(variables_, + "if (other.has$capitalized_name$()) {\n" + " $name$_.merge(other.$name$_);\n" + " $set_has_field_bit_message$;\n" + "}\n"); +} + +void ImmutableLazyMessageFieldLiteGenerator:: +GenerateParsingCode(io::Printer* printer) const { + printer->Print(variables_, + "$name$_.setByteString(input.readBytes(), extensionRegistry);\n"); + printer->Print(variables_, + "$set_has_field_bit_message$;\n"); +} + +void ImmutableLazyMessageFieldLiteGenerator:: +GenerateSerializationCode(io::Printer* printer) const { + // Do not de-serialize lazy fields. + printer->Print(variables_, + "if ($get_has_field_bit_message$) {\n" + " output.writeBytes($number$, $name$_.toByteString());\n" + "}\n"); +} + +void ImmutableLazyMessageFieldLiteGenerator:: +GenerateSerializedSizeCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($get_has_field_bit_message$) {\n" + " size += com.google.protobuf.CodedOutputStream\n" + " .computeLazyFieldSize($number$, $name$_);\n" + "}\n"); +} + +// =================================================================== + +ImmutableLazyMessageOneofFieldLiteGenerator:: +ImmutableLazyMessageOneofFieldLiteGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex, + Context* context) + : ImmutableLazyMessageFieldLiteGenerator( + descriptor, messageBitIndex, builderBitIndex, context) { + const OneofGeneratorInfo* info = + context->GetOneofGeneratorInfo(descriptor->containing_oneof()); + SetCommonOneofVariables(descriptor, info, &variables_); + variables_["lazy_type"] = "com.google.protobuf.LazyFieldLite"; +} + +ImmutableLazyMessageOneofFieldLiteGenerator:: +~ImmutableLazyMessageOneofFieldLiteGenerator() {} + +void ImmutableLazyMessageOneofFieldLiteGenerator:: +GenerateMembers(io::Printer* printer) const { + PrintExtraFieldInfo(variables_, printer); + WriteFieldDocComment(printer, descriptor_); + + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $has_oneof_case_message$;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$() {\n" + " if ($has_oneof_case_message$) {\n" + " return ($type$) (($lazy_type$) $oneof_name$_).getValue(\n" + " $type$.getDefaultInstance());\n" + " }\n" + " return $type$.getDefaultInstance();\n" + "}\n"); + + // Field.Builder setField(Field value) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void set$capitalized_name$($type$ value) {\n" + " if (value == null) {\n" + " throw new NullPointerException();\n" + " }\n" + " if (!($has_oneof_case_message$)) {\n" + " $oneof_name$_ = new $lazy_type$();\n" + " $set_oneof_case_message$;\n" + " }\n" + " (($lazy_type$) $oneof_name$_).setValue(value);\n" + "}\n"); + + // Field.Builder setField(Field.Builder builderForValue) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void set$capitalized_name$(\n" + " $type$.Builder builderForValue) {\n" + " if (!($has_oneof_case_message$)) {\n" + " $oneof_name$_ = new $lazy_type$();\n" + " $set_oneof_case_message$;\n" + " }\n" + " (($lazy_type$) $oneof_name$_).setValue(builderForValue.build());\n" + "}\n"); + + // Field.Builder mergeField(Field value) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void merge$capitalized_name$($type$ value) {\n" + " if ($has_oneof_case_message$ &&\n" + " !(($lazy_type$) $oneof_name$_).containsDefaultInstance()) {\n" + " (($lazy_type$) $oneof_name$_).setValue(\n" + " $type$.newBuilder(\n" + " get$capitalized_name$()).mergeFrom(value).buildPartial());\n" + " } else {\n" + " if (!($has_oneof_case_message$)) {\n" + " $oneof_name$_ = new $lazy_type$();\n" + " $set_oneof_case_message$;\n" + " }\n" + " (($lazy_type$) $oneof_name$_).setValue(value);\n" + " }\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 ImmutableLazyMessageOneofFieldLiteGenerator:: +GenerateBuilderMembers(io::Printer* printer) const { + // boolean hasField() + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return instance.has$capitalized_name$();\n" + "}\n"); + + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$() {\n" + " return instance.get$capitalized_name$();\n" + "}\n"); + + // 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"); + + // 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);\n" + " return this;\n" + "}\n"); + + // 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"); + + // 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"); +} + +void ImmutableLazyMessageOneofFieldLiteGenerator:: +GenerateMergingCode(io::Printer* printer) const { + printer->Print(variables_, + "if (!($has_oneof_case_message$)) {\n" + " $oneof_name$_ = new $lazy_type$();\n" + "}\n" + "(($lazy_type$) $oneof_name$_).merge(\n" + " ($lazy_type$) other.$oneof_name$_);\n" + "$set_oneof_case_message$;\n"); +} + +void ImmutableLazyMessageOneofFieldLiteGenerator:: +GenerateParsingCode(io::Printer* printer) const { + printer->Print(variables_, + "if (!($has_oneof_case_message$)) {\n" + " $oneof_name$_ = new $lazy_type$();\n" + "}\n" + "(($lazy_type$) $oneof_name$_).setByteString(\n" + " input.readBytes(), extensionRegistry);\n" + "$set_oneof_case_message$;\n"); +} + +void ImmutableLazyMessageOneofFieldLiteGenerator:: +GenerateSerializationCode(io::Printer* printer) const { + // Do not de-serialize lazy fields. + printer->Print(variables_, + "if ($has_oneof_case_message$) {\n" + " output.writeBytes(\n" + " $number$, (($lazy_type$) $oneof_name$_).toByteString());\n" + "}\n"); +} + +void ImmutableLazyMessageOneofFieldLiteGenerator:: +GenerateSerializedSizeCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($has_oneof_case_message$) {\n" + " size += com.google.protobuf.CodedOutputStream\n" + " .computeLazyFieldSize($number$, ($lazy_type$) $oneof_name$_);\n" + "}\n"); +} + +// =================================================================== + +RepeatedImmutableLazyMessageFieldLiteGenerator:: +RepeatedImmutableLazyMessageFieldLiteGenerator( + const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex, + Context* context) + : RepeatedImmutableMessageFieldLiteGenerator( + descriptor, messageBitIndex, builderBitIndex, context) { +} + + +RepeatedImmutableLazyMessageFieldLiteGenerator:: +~RepeatedImmutableLazyMessageFieldLiteGenerator() {} + +void RepeatedImmutableLazyMessageFieldLiteGenerator:: +GenerateMembers(io::Printer* printer) const { + printer->Print(variables_, + "private com.google.protobuf.Internal.ProtobufList<\n" + " com.google.protobuf.LazyFieldLite> $name$_;\n"); + PrintExtraFieldInfo(variables_, printer); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public java.util.List<$type$>\n" + " get$capitalized_name$List() {\n" + " java.util.List<$type$> list =\n" + " new java.util.ArrayList<$type$>($name$_.size());\n" + " for (com.google.protobuf.LazyFieldLite lf : $name$_) {\n" + " list.add(($type$) lf.getValue($type$.getDefaultInstance()));\n" + " }\n" + // TODO(dweis): Make this list immutable? + " return list;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public java.util.List<? extends $type$OrBuilder>\n" + " get$capitalized_name$OrBuilderList() {\n" + " return get$capitalized_name$List();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public int get$capitalized_name$Count() {\n" + " return $name$_.size();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + " return ($type$)\n" + " $name$_.get(index).getValue($type$.getDefaultInstance());\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n" + " int index) {\n" + " return ($type$OrBuilder)\n" + " $name$_.get(index).getValue($type$.getDefaultInstance());\n" + "}\n"); + + printer->Print(variables_, + "private void ensure$capitalized_name$IsMutable() {\n" + " if (!$is_mutable$) {\n" + " $name$_ = newProtobufList($name$_);\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" + " if (value == null) {\n" + " throw new NullPointerException();\n" + " }\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.set(\n" + " index, com.google.protobuf.LazyFieldLite.fromValue(value));\n" + "}\n"); + + // Builder setRepeatedField(int index, Field.Builder builderForValue) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void set$capitalized_name$(\n" + " int index, $type$.Builder builderForValue) {\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.set(index, com.google.protobuf.LazyFieldLite.fromValue(\n" + " builderForValue.build()));\n" + "}\n"); + + // Builder addRepeatedField(Field value) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void add$capitalized_name$($type$ value) {\n" + " if (value == null) {\n" + " throw new NullPointerException();\n" + " }\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.add(com.google.protobuf.LazyFieldLite.fromValue(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" + " if (value == null) {\n" + " throw new NullPointerException();\n" + " }\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.add(\n" + " index, com.google.protobuf.LazyFieldLite.fromValue(value));\n" + "}\n"); + + // Builder addRepeatedField(Field.Builder builderForValue) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void add$capitalized_name$(\n" + " $type$.Builder builderForValue) {\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.add(com.google.protobuf.LazyFieldLite.fromValue(\n" + " builderForValue.build()));\n" + "}\n"); + + // Builder addRepeatedField(int index, Field.Builder builderForValue) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void add$capitalized_name$(\n" + " int index, $type$.Builder builderForValue) {\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.add(index, com.google.protobuf.LazyFieldLite.fromValue(\n" + " builderForValue.build()));\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" + " for (com.google.protobuf.MessageLite v : values) {\n" + " $name$_.add(com.google.protobuf.LazyFieldLite.fromValue(v));\n" + " }\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 RepeatedImmutableLazyMessageFieldLiteGenerator:: +GenerateBuilderMembers(io::Printer* printer) const { + // List<Field> getRepeatedFieldList() + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n" + " return java.util.Collections.unmodifiableList(\n" + " instance.get$capitalized_name$List());\n" + "}\n"); + + // int getRepeatedFieldCount() + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public int get$capitalized_name$Count() {\n" + " return instance.get$capitalized_name$Count();\n" + "}\n"); + + // Field getRepeatedField(int index) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + " return instance.get$capitalized_name$(index);\n" + "}\n"); + + // 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"); + + // 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, builderForValue);\n" + " return this;\n" + "}\n"); + + // 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"); + + // 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"); + + // 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);\n" + " return this;\n" + "}\n"); + + // 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, builderForValue);\n" + " return this;\n" + "}\n"); + + // 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"); + + // 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"); + + // 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"); +} + +void RepeatedImmutableLazyMessageFieldLiteGenerator:: +GenerateParsingCode(io::Printer* printer) const { + printer->Print(variables_, + "if (!$is_mutable$) {\n" + " $name$_ = newProtobufList();\n" + "}\n" + "$name$_.add(new com.google.protobuf.LazyFieldLite(\n" + " extensionRegistry, input.readBytes()));\n"); +} + +void RepeatedImmutableLazyMessageFieldLiteGenerator:: +GenerateSerializationCode(io::Printer* printer) const { + printer->Print(variables_, + "for (int i = 0; i < $name$_.size(); i++) {\n" + " output.writeBytes($number$, $name$_.get(i).toByteString());\n" + "}\n"); +} + +void RepeatedImmutableLazyMessageFieldLiteGenerator:: +GenerateSerializedSizeCode(io::Printer* printer) const { + printer->Print(variables_, + "for (int i = 0; i < $name$_.size(); i++) {\n" + " size += com.google.protobuf.CodedOutputStream\n" + " .computeLazyFieldSize($number$, $name$_.get(i));\n" + "}\n"); +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/java/java_lazy_message_field_lite.h b/src/google/protobuf/compiler/java/java_lazy_message_field_lite.h new file mode 100644 index 00000000..e85ec0f3 --- /dev/null +++ b/src/google/protobuf/compiler/java/java_lazy_message_field_lite.h @@ -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. + +// Author: niwasaki@google.com (Naoki Iwasaki) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_LAZY_MESSAGE_FIELD_LITE_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_LAZY_MESSAGE_FIELD_LITE_H__ + +#include <google/protobuf/compiler/java/java_field.h> +#include <google/protobuf/compiler/java/java_message_field_lite.h> + +namespace google { +namespace protobuf { + namespace compiler { + namespace java { + class Context; // context.h + } + } +} + +namespace protobuf { +namespace compiler { +namespace java { + +class ImmutableLazyMessageFieldLiteGenerator + : public ImmutableMessageFieldLiteGenerator { + public: + explicit ImmutableLazyMessageFieldLiteGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, + int builderBitIndex, Context* context); + ~ImmutableLazyMessageFieldLiteGenerator(); + + // overroads ImmutableMessageFieldLiteGenerator ------------------------------ + void GenerateMembers(io::Printer* printer) const; + void GenerateBuilderMembers(io::Printer* printer) const; + void GenerateInitializationCode(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateParsingCode(io::Printer* printer) const; + void GenerateSerializationCode(io::Printer* printer) const; + void GenerateSerializedSizeCode(io::Printer* printer) const; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableLazyMessageFieldLiteGenerator); +}; + +class ImmutableLazyMessageOneofFieldLiteGenerator + : public ImmutableLazyMessageFieldLiteGenerator { + public: + ImmutableLazyMessageOneofFieldLiteGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, + int builderBitIndex, Context* context); + ~ImmutableLazyMessageOneofFieldLiteGenerator(); + + void GenerateMembers(io::Printer* printer) const; + void GenerateBuilderMembers(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateParsingCode(io::Printer* printer) const; + void GenerateSerializationCode(io::Printer* printer) const; + void GenerateSerializedSizeCode(io::Printer* printer) const; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableLazyMessageOneofFieldLiteGenerator); +}; + +class RepeatedImmutableLazyMessageFieldLiteGenerator + : public RepeatedImmutableMessageFieldLiteGenerator { + public: + explicit RepeatedImmutableLazyMessageFieldLiteGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, + int builderBitIndex, Context* context); + ~RepeatedImmutableLazyMessageFieldLiteGenerator(); + + // overroads RepeatedImmutableMessageFieldLiteGenerator ---------------------- + void GenerateMembers(io::Printer* printer) const; + void GenerateBuilderMembers(io::Printer* printer) const; + void GenerateParsingCode(io::Printer* printer) const; + void GenerateSerializationCode(io::Printer* printer) const; + void GenerateSerializedSizeCode(io::Printer* printer) const; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableLazyMessageFieldLiteGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_LAZY_MESSAGE_FIELD_LITE_H__ diff --git a/src/google/protobuf/compiler/java/java_map_field.cc b/src/google/protobuf/compiler/java/java_map_field.cc index cf1ef589..f25970e5 100644 --- a/src/google/protobuf/compiler/java/java_map_field.cc +++ b/src/google/protobuf/compiler/java/java_map_field.cc @@ -133,9 +133,11 @@ void SetMessageVariables(const FieldDescriptor* descriptor, (*variables)["set_mutable_bit_parser"] = GenerateSetBitMutableLocal(builderBitIndex); + (*variables)["default_entry"] = (*variables)["capitalized_name"] + + "DefaultEntryHolder.defaultEntry"; if (HasDescriptorMethods(descriptor->file())) { (*variables)["lite"] = ""; - (*variables)["map_field_parameter"] = (*variables)["name"] + "DefaultEntry"; + (*variables)["map_field_parameter"] = (*variables)["default_entry"]; (*variables)["descriptor"] = name_resolver->GetImmutableClassName(descriptor->file()) + ".internal_" + UniqueFileScopeIdentifier(descriptor->message_type()) + @@ -198,26 +200,20 @@ GenerateInterfaceMembers(io::Printer* printer) const { } void ImmutableMapFieldGenerator:: -GenerateStaticInitializationCode(io::Printer* printer) const { - printer->Print( - variables_, - "$name$DefaultEntry =\n" - " com.google.protobuf.MapEntry$lite$\n" - " .<$type_parameters$>newDefaultInstance(\n" - " $descriptor$\n" - " $key_wire_type$,\n" - " $key_default_value$,\n" - " $value_wire_type$,\n" - " $value_default_value$);\n" - "\n"); -} - -void ImmutableMapFieldGenerator:: GenerateMembers(io::Printer* printer) const { printer->Print( variables_, - "private static final com.google.protobuf.MapEntry$lite$<\n" - " $type_parameters$> $name$DefaultEntry;\n"); + "private static final class $capitalized_name$DefaultEntryHolder {\n" + " static final com.google.protobuf.MapEntry$lite$<\n" + " $type_parameters$> defaultEntry =\n" + " com.google.protobuf.MapEntry$lite$\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$lite$<\n" @@ -291,7 +287,10 @@ GenerateBuilderMembers(io::Printer* printer) const { " if ($name$_ == null) {\n" " $name$_ = com.google.protobuf.MapField$lite$.newMapField(\n" " $map_field_parameter$);\n" - " }\n" + " }\n" + " if (!$name$_.isMutable()) {\n" + " $name$_ = $name$_.copy();\n" + " }\n" " return $name$_;\n" "}\n"); if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { @@ -381,10 +380,8 @@ void ImmutableMapFieldGenerator:: GenerateBuildingCode(io::Printer* printer) const { printer->Print( variables_, - // We do a copy of the map field to ensure that the built result is - // immutable. Implementation of this copy() method can do copy-on-write - // to defer this copy until further modifications are made on the field. - "result.$name$_ = internalGet$capitalized_name$().copy();\n"); + "result.$name$_ = internalGet$capitalized_name$();\n" + "result.$name$_.makeImmutable();\n"); } void ImmutableMapFieldGenerator:: @@ -402,7 +399,7 @@ GenerateParsingCode(io::Printer* printer) const { variables_, "com.google.protobuf.ByteString bytes = input.readBytes();\n" "com.google.protobuf.MapEntry$lite$<$type_parameters$>\n" - "$name$ = $name$DefaultEntry.getParserForType().parseFrom(bytes);\n"); + "$name$ = $default_entry$.getParserForType().parseFrom(bytes);\n"); printer->Print( variables_, "if ($value_enum_type$.valueOf($name$.getValue()) == null) {\n" @@ -415,7 +412,7 @@ GenerateParsingCode(io::Printer* printer) const { variables_, "com.google.protobuf.MapEntry$lite$<$type_parameters$>\n" "$name$ = input.readMessage(\n" - " $name$DefaultEntry.getParserForType(), extensionRegistry);\n" + " $default_entry$.getParserForType(), extensionRegistry);\n" "$name$_.getMutableMap().put($name$.getKey(), $name$.getValue());\n"); } } @@ -432,7 +429,7 @@ GenerateSerializationCode(io::Printer* printer) const { "for (java.util.Map.Entry<$type_parameters$> entry\n" " : internalGet$capitalized_name$().getMap().entrySet()) {\n" " com.google.protobuf.MapEntry$lite$<$type_parameters$>\n" - " $name$ = $name$DefaultEntry.newBuilderForType()\n" + " $name$ = $default_entry$.newBuilderForType()\n" " .setKey(entry.getKey())\n" " .setValue(entry.getValue())\n" " .build();\n" @@ -447,7 +444,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const { "for (java.util.Map.Entry<$type_parameters$> entry\n" " : internalGet$capitalized_name$().getMap().entrySet()) {\n" " com.google.protobuf.MapEntry$lite$<$type_parameters$>\n" - " $name$ = $name$DefaultEntry.newBuilderForType()\n" + " $name$ = $default_entry$.newBuilderForType()\n" " .setKey(entry.getKey())\n" " .setValue(entry.getValue())\n" " .build();\n" diff --git a/src/google/protobuf/compiler/java/java_map_field.h b/src/google/protobuf/compiler/java/java_map_field.h index 3e6dd973..80a94f45 100644 --- a/src/google/protobuf/compiler/java/java_map_field.h +++ b/src/google/protobuf/compiler/java/java_map_field.h @@ -60,7 +60,6 @@ class ImmutableMapFieldGenerator : public ImmutableFieldGenerator { void GenerateSerializationCode(io::Printer* printer) const; void GenerateSerializedSizeCode(io::Printer* printer) const; void GenerateFieldBuilderInitializationCode(io::Printer* printer) const; - void GenerateStaticInitializationCode(io::Printer* printer) const; void GenerateEqualsCode(io::Printer* printer) const; void GenerateHashCode(io::Printer* printer) const; diff --git a/src/google/protobuf/compiler/java/java_map_field_lite.cc b/src/google/protobuf/compiler/java/java_map_field_lite.cc new file mode 100644 index 00000000..ccc1b32e --- /dev/null +++ b/src/google/protobuf/compiler/java/java_map_field_lite.cc @@ -0,0 +1,461 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <google/protobuf/compiler/java/java_map_field_lite.h> + +#include <google/protobuf/compiler/java/java_context.h> +#include <google/protobuf/compiler/java/java_doc_comment.h> +#include <google/protobuf/compiler/java/java_helpers.h> +#include <google/protobuf/compiler/java/java_name_resolver.h> +#include <google/protobuf/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"); +} + +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)); + } +} + +string WireType(const FieldDescriptor* field) { + return "com.google.protobuf.WireFormat.FieldType." + + string(FieldTypeName(field->type())); +} + +void SetMessageVariables(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex, + const FieldGeneratorInfo* info, + ClassNameResolver* name_resolver, + map<string, string>* variables) { + SetCommonFieldVariables(descriptor, info, variables); + + (*variables)["type"] = + name_resolver->GetImmutableClassName(descriptor->message_type()); + const FieldDescriptor* key = KeyField(descriptor); + const FieldDescriptor* value = ValueField(descriptor); + (*variables)["key_type"] = TypeName(key, name_resolver, false); + (*variables)["boxed_key_type"] = TypeName(key, name_resolver, true); + (*variables)["key_wire_type"] = WireType(key); + (*variables)["key_default_value"] = DefaultValue(key, true, name_resolver); + 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)["on_changed"] = + HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : ""; + + (*variables)["default_entry"] = (*variables)["capitalized_name"] + + "DefaultEntryHolder.defaultEntry"; + (*variables)["lite"] = "Lite"; + (*variables)["descriptor"] = ""; +} + +} // namespace + +ImmutableMapFieldLiteGenerator:: +ImmutableMapFieldLiteGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex, + Context* context) + : descriptor_(descriptor), messageBitIndex_(messageBitIndex), + builderBitIndex_(builderBitIndex), context_(context), + name_resolver_(context->GetNameResolver()) { + SetMessageVariables(descriptor, messageBitIndex, builderBitIndex, + context->GetFieldGeneratorInfo(descriptor), + name_resolver_, &variables_); +} + +ImmutableMapFieldLiteGenerator:: +~ImmutableMapFieldLiteGenerator() {} + +int ImmutableMapFieldLiteGenerator::GetNumBitsForMessage() const { + return 0; +} + +int ImmutableMapFieldLiteGenerator::GetNumBitsForBuilder() const { + return 0; +} + +void ImmutableMapFieldLiteGenerator:: +GenerateInterfaceMembers(io::Printer* printer) const { + if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$java.util.Map<$boxed_key_type$, $value_enum_type$>\n" + "get$capitalized_name$();\n"); + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$java.util.Map<$type_parameters$>\n" + "get$capitalized_name$Value();\n"); + } + } else { + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$java.util.Map<$type_parameters$>\n" + "get$capitalized_name$();\n"); + } +} + +void ImmutableMapFieldLiteGenerator:: +GenerateMembers(io::Printer* printer) const { + printer->Print( + variables_, + "private static final class $capitalized_name$DefaultEntryHolder {\n" + " static final com.google.protobuf.MapEntry$lite$<\n" + " $type_parameters$> defaultEntry =\n" + " com.google.protobuf.MapEntry$lite$\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$lite$<\n" + " $type_parameters$> $name$_ =\n" + " com.google.protobuf.MapField$lite$.emptyMapField();\n" + "private com.google.protobuf.MapField$lite$<$type_parameters$>\n" + "internalGet$capitalized_name$() {\n" + " return $name$_;\n" + "}\n" + "private com.google.protobuf.MapField$lite$<$type_parameters$>\n" + "internalGetMutable$capitalized_name$() {\n" + " if (!$name$_.isMutable()) {\n" + " $name$_ = $name$_.copy();\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"); + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" + "get$capitalized_name$Value() {\n" + " return internalGet$capitalized_name$().getMap();\n" + "}\n"); + } + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" + "get$capitalized_name$() {\n" + " return new com.google.protobuf.Internal.MapAdapter<\n" + " $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n" + " internalGet$capitalized_name$().getMap(),\n" + " $name$ValueConverter);\n" + "}\n"); + } else { + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "public java.util.Map<$type_parameters$> get$capitalized_name$() {\n" + " return internalGet$capitalized_name$().getMap();\n" + "}\n"); + } + + // 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$() {\n" + " return new com.google.protobuf.Internal.MapAdapter<\n" + " $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n" + " internalGetMutable$capitalized_name$().getMutableMap(),\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$Value() {\n" + " return internalGetMutable$capitalized_name$().getMutableMap();\n" + "}\n"); + } + } else { + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "private java.util.Map<$type_parameters$>\n" + "getMutable$capitalized_name$() {\n" + " return internalGetMutable$capitalized_name$().getMutableMap();\n" + "}\n"); + } +} + +void ImmutableMapFieldLiteGenerator:: +GenerateBuilderMembers(io::Printer* printer) const { + if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" + "get$capitalized_name$() {\n" + " return instance.get$capitalized_name$();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" + "getMutable$capitalized_name$() {\n" + " copyOnWrite();\n" + " return instance.getMutable$capitalized_name$();\n" + "}\n"); + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" + "get$capitalized_name$Value() {\n" + " return instance.get$capitalized_name$Value();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" + "getMutable$capitalized_name$Value() {\n" + " copyOnWrite();\n" + " return instance.getMutable$capitalized_name$Value();\n" + "}\n"); + } + } else { + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "public java.util.Map<$type_parameters$> get$capitalized_name$() {\n" + " return instance.get$capitalized_name$();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "public java.util.Map<$type_parameters$>\n" + "getMutable$capitalized_name$() {\n" + " copyOnWrite();\n" + " return instance.getMutable$capitalized_name$();\n" + "}\n"); + } +} + +void ImmutableMapFieldLiteGenerator:: +GenerateFieldBuilderInitializationCode(io::Printer* printer) const { + // Nothing to initialize. +} + +void ImmutableMapFieldLiteGenerator:: +GenerateInitializationCode(io::Printer* printer) const { + // Nothing to initialize. +} + +void ImmutableMapFieldLiteGenerator:: +GenerateMergingCode(io::Printer* printer) const { + printer->Print( + variables_, + "internalGetMutable$capitalized_name$().mergeFrom(\n" + " other.internalGet$capitalized_name$());\n"); +} + +void ImmutableMapFieldLiteGenerator:: +GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const { + printer->Print(variables_, + "$name$_.makeImmutable();\n"); +} + +void ImmutableMapFieldLiteGenerator:: +GenerateParsingCode(io::Printer* printer) const { + printer->Print( + variables_, + "if (!$name$_.isMutable()) {\n" + " $name$_ = $name$_.copy();\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$lite$<$type_parameters$>\n" + "$name$ = $default_entry$.getParserForType().parseFrom(bytes);\n"); + printer->Print( + variables_, + "if ($value_enum_type$.valueOf($name$.getValue()) == null) {\n" + " unknownFields.mergeLengthDelimitedField($number$, bytes);\n" + "} else {\n" + " $name$_.getMutableMap().put($name$.getKey(), $name$.getValue());\n" + "}\n"); + } else { + printer->Print( + variables_, + "com.google.protobuf.MapEntry$lite$<$type_parameters$>\n" + "$name$ = input.readMessage(\n" + " $default_entry$.getParserForType(), extensionRegistry);\n" + "$name$_.getMutableMap().put($name$.getKey(), $name$.getValue());\n"); + } +} + +void ImmutableMapFieldLiteGenerator:: +GenerateParsingDoneCode(io::Printer* printer) const { + // Nothing to do here. +} + +void ImmutableMapFieldLiteGenerator:: +GenerateSerializationCode(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$lite$<$type_parameters$>\n" + " $name$ = $default_entry$.newBuilderForType()\n" + " .setKey(entry.getKey())\n" + " .setValue(entry.getValue())\n" + " .build();\n" + " output.writeMessage($number$, $name$);\n" + "}\n"); +} + +void ImmutableMapFieldLiteGenerator:: +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$lite$<$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 ImmutableMapFieldLiteGenerator:: +GenerateEqualsCode(io::Printer* printer) const { + printer->Print( + variables_, + "result = result && internalGet$capitalized_name$().equals(\n" + " other.internalGet$capitalized_name$());\n"); +} + +void ImmutableMapFieldLiteGenerator:: +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"); +} + +string ImmutableMapFieldLiteGenerator::GetBoxedType() const { + return name_resolver_->GetImmutableClassName(descriptor_->message_type()); +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/java/java_map_field_lite.h b/src/google/protobuf/compiler/java/java_map_field_lite.h new file mode 100644 index 00000000..82472602 --- /dev/null +++ b/src/google/protobuf/compiler/java/java_map_field_lite.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_JAVA_MAP_FIELD_LITE_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_MAP_FIELD_LITE_H__ + +#include <google/protobuf/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, + int builderBitIndex, Context* context); + ~ImmutableMapFieldLiteGenerator(); + + // implements ImmutableFieldLiteGenerator ------------------------------------ + int GetNumBitsForMessage() const; + int GetNumBitsForBuilder() const; + void GenerateInterfaceMembers(io::Printer* printer) const; + void GenerateMembers(io::Printer* printer) const; + void GenerateBuilderMembers(io::Printer* printer) const; + void GenerateInitializationCode(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const; + void GenerateParsingCode(io::Printer* printer) const; + void GenerateParsingDoneCode(io::Printer* printer) const; + void GenerateSerializationCode(io::Printer* printer) const; + void GenerateSerializedSizeCode(io::Printer* printer) const; + void GenerateFieldBuilderInitializationCode(io::Printer* printer) const; + void GenerateEqualsCode(io::Printer* printer) const; + void GenerateHashCode(io::Printer* printer) const; + + string GetBoxedType() const; + + private: + const FieldDescriptor* descriptor_; + map<string, string> variables_; + const int messageBitIndex_; + const int builderBitIndex_; + 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/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc index e982a17b..09b0fd94 100644 --- a/src/google/protobuf/compiler/java/java_message.cc +++ b/src/google/protobuf/compiler/java/java_message.cc @@ -49,6 +49,8 @@ #include <google/protobuf/compiler/java/java_extension.h> #include <google/protobuf/compiler/java/java_generator_factory.h> #include <google/protobuf/compiler/java/java_helpers.h> +#include <google/protobuf/compiler/java/java_message_builder.h> +#include <google/protobuf/compiler/java/java_message_builder_lite.h> #include <google/protobuf/compiler/java/java_name_resolver.h> #include <google/protobuf/io/coded_stream.h> #include <google/protobuf/io/printer.h> @@ -93,43 +95,46 @@ ImmutableMessageGenerator::ImmutableMessageGenerator( : MessageGenerator(descriptor), context_(context), name_resolver_(context->GetNameResolver()), field_generators_(descriptor, context_) { + GOOGLE_CHECK_NE( + FileOptions::LITE_RUNTIME, descriptor->file()->options().optimize_for()); } ImmutableMessageGenerator::~ImmutableMessageGenerator() {} void ImmutableMessageGenerator::GenerateStaticVariables(io::Printer* printer) { - if (HasDescriptorMethods(descriptor_)) { - // 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. - - map<string, string> vars; - vars["identifier"] = UniqueFileScopeIdentifier(descriptor_); - vars["index"] = SimpleItoa(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 "; - } - - // The descriptor for this type. - printer->Print(vars, - "$private$static final com.google.protobuf.Descriptors.Descriptor\n" - " internal_$identifier$_descriptor;\n"); + // 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. - // And the FieldAccessorTable. - GenerateFieldAccessorTable(printer); + map<string, string> vars; + vars["identifier"] = UniqueFileScopeIdentifier(descriptor_); + vars["index"] = SimpleItoa(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 "; + } + + // 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 com.google.protobuf.Descriptors.Descriptor\n" + " internal_$identifier$_descriptor;\n"); + + // And the FieldAccessorTable. + GenerateFieldAccessorTable(printer); // Generate static members for all nested types. for (int i = 0; i < descriptor_->nested_type_count(); i++) { @@ -139,39 +144,42 @@ void ImmutableMessageGenerator::GenerateStaticVariables(io::Printer* printer) { } } -void ImmutableMessageGenerator::GenerateStaticVariableInitializers( +int ImmutableMessageGenerator::GenerateStaticVariableInitializers( io::Printer* printer) { - if (HasDescriptorMethods(descriptor_)) { - map<string, string> vars; - vars["identifier"] = UniqueFileScopeIdentifier(descriptor_); - vars["index"] = SimpleItoa(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"); - } else { - printer->Print(vars, - "internal_$identifier$_descriptor =\n" - " internal_$parent$_descriptor.getNestedTypes().get($index$);\n"); - } + int bytecode_estimate = 0; + map<string, string> vars; + vars["identifier"] = UniqueFileScopeIdentifier(descriptor_); + vars["index"] = SimpleItoa(descriptor_->index()); + vars["classname"] = name_resolver_->GetImmutableClassName(descriptor_); + if (descriptor_->containing_type() != NULL) { + vars["parent"] = UniqueFileScopeIdentifier( + descriptor_->containing_type()); + } - // And the FieldAccessorTable. - GenerateFieldAccessorTableInitializer(printer); + // 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? - ImmutableMessageGenerator(descriptor_->nested_type(i), context_) - .GenerateStaticVariableInitializers(printer); + bytecode_estimate += + ImmutableMessageGenerator(descriptor_->nested_type(i), context_) + .GenerateStaticVariableInitializers(printer); } + return bytecode_estimate; } void ImmutableMessageGenerator:: @@ -191,8 +199,9 @@ GenerateFieldAccessorTable(io::Printer* printer) { " internal_$identifier$_fieldAccessorTable;\n"); } -void ImmutableMessageGenerator:: +int ImmutableMessageGenerator:: GenerateFieldAccessorTableInitializer(io::Printer* printer) { + int bytecode_estimate = 10; printer->Print( "internal_$identifier$_fieldAccessorTable = new\n" " com.google.protobuf.GeneratedMessage.FieldAccessorTable(\n" @@ -203,6 +212,7 @@ GenerateFieldAccessorTableInitializer(io::Printer* printer) { 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); @@ -210,51 +220,33 @@ GenerateFieldAccessorTableInitializer(io::Printer* printer) { 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) { if (descriptor_->extension_range_count() > 0) { - if (HasDescriptorMethods(descriptor_)) { - printer->Print( - "public interface $classname$OrBuilder extends\n" - " $extra_interfaces$\n" - " com.google.protobuf.GeneratedMessage.\n" - " ExtendableMessageOrBuilder<$classname$> {\n", - "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), - "classname", descriptor_->name()); - } else { - printer->Print( - "public interface $classname$OrBuilder extends \n" - " $extra_interfaces$\n" - " com.google.protobuf.GeneratedMessageLite.\n" - " ExtendableMessageOrBuilder<\n" - " $classname$, $classname$.Builder> {\n", - "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), - "classname", descriptor_->name()); - } + printer->Print( + "public interface $classname$OrBuilder extends\n" + " $extra_interfaces$\n" + " com.google.protobuf.GeneratedMessage.\n" + " ExtendableMessageOrBuilder<$classname$> {\n", + "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), + "classname", descriptor_->name()); } else { - if (HasDescriptorMethods(descriptor_)) { - printer->Print( - "public interface $classname$OrBuilder extends\n" - " $extra_interfaces$\n" - " com.google.protobuf.MessageOrBuilder {\n", - "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), - "classname", descriptor_->name()); - } else { - printer->Print( - "public interface $classname$OrBuilder extends\n" - " $extra_interfaces$\n" - " com.google.protobuf.MessageLiteOrBuilder {\n", - "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), - "classname", descriptor_->name()); - } + printer->Print( + "public interface $classname$OrBuilder extends\n" + " $extra_interfaces$\n" + " com.google.protobuf.MessageOrBuilder {\n", + "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), + "classname", descriptor_->name()); } printer->Indent(); @@ -279,98 +271,71 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { variables["static"] = is_own_file ? " " : " static "; variables["classname"] = descriptor_->name(); variables["extra_interfaces"] = ExtraMessageInterfaces(descriptor_); - variables["lite"] = HasDescriptorMethods(descriptor_) ? "" : "Lite"; WriteMessageDocComment(printer, descriptor_); // The builder_type stores the super type name of the nested Builder class. string builder_type; if (descriptor_->extension_range_count() > 0) { - if (HasDescriptorMethods(descriptor_)) { - printer->Print(variables, - "public $static$final class $classname$ extends\n" - " com.google.protobuf.GeneratedMessage.ExtendableMessage<\n" - " $classname$> implements\n" - " $extra_interfaces$\n" - " $classname$OrBuilder {\n"); - } else { - printer->Print(variables, - "public $static$final class $classname$ extends\n" - " com.google.protobuf.GeneratedMessageLite.ExtendableMessage<\n" - " $classname$, $classname$.Builder> implements\n" - " $extra_interfaces$\n" - " $classname$OrBuilder {\n"); - } + printer->Print(variables, + "public $static$final class $classname$ extends\n" + " com.google.protobuf.GeneratedMessage.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_), - variables["lite"]); + "com.google.protobuf.GeneratedMessage.ExtendableBuilder<$0, ?>", + name_resolver_->GetImmutableClassName(descriptor_)); } else { - if (HasDescriptorMethods(descriptor_)) { - printer->Print(variables, - "public $static$final class $classname$ extends\n" - " com.google.protobuf.GeneratedMessage implements\n" - " $extra_interfaces$\n" - " $classname$OrBuilder {\n"); - } else { - printer->Print(variables, - "public $static$final class $classname$ extends\n" - " com.google.protobuf.GeneratedMessageLite<\n" - " $classname$, $classname$.Builder> implements\n" - " $extra_interfaces$\n" - " $classname$OrBuilder {\n"); - } + printer->Print(variables, + "public $static$final class $classname$ extends\n" + " com.google.protobuf.GeneratedMessage implements\n" + " $extra_interfaces$\n" + " $classname$OrBuilder {\n"); - builder_type = strings::Substitute( - "com.google.protobuf.GeneratedMessage$0.Builder", - variables["lite"]); + builder_type = "com.google.protobuf.GeneratedMessage.Builder"; } printer->Indent(); - if (HasDescriptorMethods(descriptor_)) { - // 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"); - } + // 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"); - if (HasDescriptorMethods(descriptor_)) { + printer->Print( + "@java.lang.Override\n" + "public final com.google.protobuf.UnknownFieldSet\n" + "getUnknownFields() {\n"); + if (PreserveUnknownFields(descriptor_)) { printer->Print( - "@java.lang.Override\n" - "public final com.google.protobuf.UnknownFieldSet\n" - "getUnknownFields() {\n"); - if (PreserveUnknownFields(descriptor_)) { - printer->Print( - " return this.unknownFields;\n"); - } else { - printer->Print( - " return com.google.protobuf.UnknownFieldSet.getDefaultInstance();\n"); - } + " return this.unknownFields;\n"); + } else { printer->Print( - "}\n"); + " return com.google.protobuf.UnknownFieldSet.getDefaultInstance();\n"); } + printer->Print( + "}\n"); if (HasGeneratedMethods(descriptor_)) { GenerateParsingConstructor(printer); } - GenerateDescriptorMethods(printer, false); - GenerateParser(printer); + GenerateDescriptorMethods(printer); // Nested types for (int i = 0; i < descriptor_->enum_type_count(); i++) { @@ -480,7 +445,7 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { } if (HasGeneratedMethods(descriptor_)) { - GenerateIsInitialized(printer, MEMOIZE); + GenerateIsInitialized(printer); GenerateMessageSerializationMethods(printer); } @@ -501,78 +466,39 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { // Carefully initialize the default instance in such a way that it doesn't // conflict with other initialization. printer->Print( - "private static final $classname$ defaultInstance;\n", + "private static final $classname$ DEFAULT_INSTANCE;\n", "classname", name_resolver_->GetImmutableClassName(descriptor_)); - if (HasDescriptorMethods(descriptor_)) { - printer->Print( - "static {\n" - " defaultInstance = new $classname$();\n" - "}\n" - "\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_)); - } else { - // LITE_RUNTIME only has one constructor. - printer->Print( - "static {\n" - " defaultInstance = new $classname$(\n" - " com.google.protobuf.Internal\n" - " .EMPTY_CODED_INPUT_STREAM,\n" - " com.google.protobuf.ExtensionRegistryLite\n" - " .getEmptyRegistry());\n" - "}\n" - "\n", - "classname", descriptor_->name()); - } + printer->Print( + "static {\n" + " DEFAULT_INSTANCE = new $classname$();\n" + "}\n" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + printer->Print( "public static $classname$ getDefaultInstance() {\n" - " return defaultInstance;\n" + " return DEFAULT_INSTANCE;\n" "}\n" "\n", "classname", name_resolver_->GetImmutableClassName(descriptor_)); - if (HasDescriptorMethods(descriptor_)) { - // LITE_RUNTIME implements this at the GeneratedMessageLite level. - printer->Print( - "public $classname$ getDefaultInstanceForType() {\n" - " return defaultInstance;\n" - "}\n" - "\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_)); - } else { - // LITE_RUNTIME uses this to implement the *ForType methods at the - // GeneratedMessageLite level. - printer->Print( - "static {" - " com.google.protobuf.GeneratedMessageLite.onLoad(\n" - " $classname$.class, new com.google.protobuf.GeneratedMessageLite\n" - " .PrototypeHolder<$classname$, Builder>(\n" - " defaultInstance, PARSER));" - "}\n" - "\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_)); - } + GenerateParser(printer); + + printer->Print( + "public $classname$ getDefaultInstanceForType() {\n" + " return DEFAULT_INSTANCE;\n" + "}\n" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); - // Extensions must be declared after the defaultInstance is initialized - // because the defaultInstance is used by the extension to lazily retrieve + // 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); } - // Some fields also have static members that must be initialized after we - // have the default instance available. - printer->Print( - "static {\n"); - printer->Indent(); - for (int i = 0; i < descriptor_->field_count(); i++) { - field_generators_.get(descriptor_->field(i)) - .GenerateStaticInitializationCode(printer); - } - printer->Outdent(); - printer->Print( - "}\n"); - printer->Outdent(); printer->Print("}\n\n"); } @@ -609,35 +535,17 @@ GenerateMessageSerializationMethods(io::Printer* printer) { if (descriptor_->extension_range_count() > 0) { if (descriptor_->options().message_set_wire_format()) { - if (HasDescriptorMethods(descriptor_)) { - printer->Print( - "com.google.protobuf.GeneratedMessage\n" - " .ExtendableMessage<$classname$>.ExtensionWriter\n" - " extensionWriter = newMessageSetExtensionWriter();\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_)); - } else { - printer->Print( - "com.google.protobuf.GeneratedMessageLite\n" - " .ExtendableMessage<$classname$, $classname$.Builder>\n" - " .ExtensionWriter extensionWriter =\n" - " newMessageSetExtensionWriter();\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_)); - } + printer->Print( + "com.google.protobuf.GeneratedMessage\n" + " .ExtendableMessage<$classname$>.ExtensionWriter\n" + " extensionWriter = newMessageSetExtensionWriter();\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); } else { - if (HasDescriptorMethods(descriptor_)) { - printer->Print( - "com.google.protobuf.GeneratedMessage\n" - " .ExtendableMessage<$classname$>.ExtensionWriter\n" - " extensionWriter = newExtensionWriter();\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_)); - } else { - printer->Print( - "com.google.protobuf.GeneratedMessageLite\n" - " .ExtendableMessage<$classname$, $classname$.Builder>\n" - " .ExtensionWriter extensionWriter =\n" - " newExtensionWriter();\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_)); - } + printer->Print( + "com.google.protobuf.GeneratedMessage\n" + " .ExtendableMessage<$classname$>.ExtensionWriter\n" + " extensionWriter = newExtensionWriter();\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); } } @@ -657,8 +565,7 @@ GenerateMessageSerializationMethods(io::Printer* printer) { } if (PreserveUnknownFields(descriptor_)) { - if (descriptor_->options().message_set_wire_format() - && HasDescriptorMethods(descriptor_)) { + if (descriptor_->options().message_set_wire_format()) { printer->Print( "unknownFields.writeAsMessageSetTo(output);\n"); } else { @@ -694,8 +601,7 @@ GenerateMessageSerializationMethods(io::Printer* printer) { } if (PreserveUnknownFields(descriptor_)) { - if (descriptor_->options().message_set_wire_format() - && HasDescriptorMethods(descriptor_)) { + if (descriptor_->options().message_set_wire_format()) { printer->Print( "size += unknownFields.getSerializedSizeAsMessageSet();\n"); } else { @@ -792,609 +698,115 @@ void ImmutableMessageGenerator::GenerateSerializeOneExtensionRange( // =================================================================== void ImmutableMessageGenerator::GenerateBuilder(io::Printer* printer) { - if (HasDescriptorMethods(descriptor_)) { - // LITE_RUNTIME implements this at the GeneratedMessageLite level. - printer->Print( - "public Builder newBuilderForType() { return newBuilder(); }\n"); - } + // LITE_RUNTIME implements this at the GeneratedMessageLite level. + printer->Print( + "public Builder newBuilderForType() { return newBuilder(); }\n"); printer->Print( "public static Builder newBuilder() {\n" - " return defaultInstance.toBuilder();\n" + " return DEFAULT_INSTANCE.toBuilder();\n" "}\n" "public static Builder newBuilder($classname$ prototype) {\n" - " return defaultInstance.toBuilder().mergeFrom(prototype);\n" + " return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n" "}\n" "public Builder toBuilder() {\n" - " return this == defaultInstance\n" + " return this == DEFAULT_INSTANCE\n" " ? new Builder() : new Builder().mergeFrom(this);\n" "}\n" "\n", "classname", name_resolver_->GetImmutableClassName(descriptor_)); - if (HasNestedBuilders(descriptor_)) { - printer->Print( - "@java.lang.Override\n" - "protected Builder newBuilderForType(\n" - " com.google.protobuf.GeneratedMessage.BuilderParent parent) {\n" - " Builder builder = new Builder(parent);\n" - " return builder;\n" - "}\n"); - } - - WriteMessageDocComment(printer, descriptor_); - - if (descriptor_->extension_range_count() > 0) { - if (HasDescriptorMethods(descriptor_)) { - printer->Print( - "public static final class Builder extends\n" - " com.google.protobuf.GeneratedMessage.ExtendableBuilder<\n" - " $classname$, Builder> implements\n" - " $extra_interfaces$\n" - " $classname$OrBuilder {\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_), - "extra_interfaces", ExtraBuilderInterfaces(descriptor_)); - } else { - printer->Print( - "public static final class Builder extends\n" - " com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<\n" - " $classname$, Builder> implements\n" - " $extra_interfaces$\n" - " $classname$OrBuilder {\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_), - "extra_interfaces", ExtraBuilderInterfaces(descriptor_)); - } - } else { - if (HasDescriptorMethods(descriptor_)) { - printer->Print( - "public static final class Builder extends\n" - " com.google.protobuf.GeneratedMessage.Builder<Builder> implements\n" - " $extra_interfaces$\n" - " $classname$OrBuilder {\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_), - "extra_interfaces", ExtraBuilderInterfaces(descriptor_)); - } else { - printer->Print( - "public static final class Builder extends\n" - " com.google.protobuf.GeneratedMessageLite.Builder<\n" - " $classname$, Builder>\n" - " implements\n" - " $extra_interfaces$\n" - " $classname$OrBuilder {\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_), - "extra_interfaces", ExtraBuilderInterfaces(descriptor_)); - } - } - printer->Indent(); - - GenerateDescriptorMethods(printer, true); - GenerateCommonBuilderMethods(printer); - - if (HasGeneratedMethods(descriptor_)) { - GenerateIsInitialized(printer, DONT_MEMOIZE); - GenerateBuilderParsingMethods(printer); - } - - // oneof - map<string, string> vars; - for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { - vars["oneof_name"] = context_->GetOneofGeneratorInfo( - descriptor_->oneof_decl(i))->name; - vars["oneof_capitalized_name"] = context_->GetOneofGeneratorInfo( - descriptor_->oneof_decl(i))->capitalized_name; - vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->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.valueOf(\n" - " $oneof_name$Case_);\n" - "}\n" - "\n" - "public Builder clear$oneof_capitalized_name$() {\n" - " $oneof_name$Case_ = 0;\n" - " $oneof_name$_ = null;\n"); - if (HasDescriptorMethods(descriptor_)) { - printer->Print(" onChanged();\n"); - } - printer->Print( - " return this;\n" - "}\n" - "\n"); - } - - if (GenerateHasBits(descriptor_)) { - // 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); - } - - if (!PreserveUnknownFields(descriptor_)) { - printer->Print( - "public final Builder setUnknownFields(\n" - " final com.google.protobuf.UnknownFieldSet unknownFields) {\n" - " return this;\n" - "}\n" - "\n" - "public final Builder mergeUnknownFields(\n" - " final com.google.protobuf.UnknownFieldSet unknownFields) {\n" - " return this;\n" - "}\n" - "\n"); - } - printer->Print( - "\n" - "// @@protoc_insertion_point(builder_scope:$full_name$)\n", - "full_name", descriptor_->full_name()); - - printer->Outdent(); - printer->Print("}\n"); + "@java.lang.Override\n" + "protected Builder newBuilderForType(\n" + " com.google.protobuf.GeneratedMessage.BuilderParent parent) {\n" + " Builder builder = new Builder(parent);\n" + " return builder;\n" + "}\n"); + + MessageBuilderGenerator builderGenerator(descriptor_, context_); + builderGenerator.Generate(printer); } void ImmutableMessageGenerator:: -GenerateDescriptorMethods(io::Printer* printer, bool is_builder) { - if (HasDescriptorMethods(descriptor_)) { - 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_)); - } - 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", SimpleItoa(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"); - if (is_builder) { - 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", SimpleItoa(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"); - } - } +GenerateDescriptorMethods(io::Printer* printer) { + if (!descriptor_->options().no_standard_descriptor_accessor()) { printer->Print( - "protected com.google.protobuf.GeneratedMessage.FieldAccessorTable\n" - " internalGetFieldAccessorTable() {\n" - " return $fileclass$.internal_$identifier$_fieldAccessorTable\n" - " .ensureFieldAccessorsInitialized(\n" - " $classname$.class, $classname$.Builder.class);\n" + "public static final com.google.protobuf.Descriptors.Descriptor\n" + " getDescriptor() {\n" + " return $fileclass$.internal_$identifier$_descriptor;\n" "}\n" "\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_), "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()), "identifier", UniqueFileScopeIdentifier(descriptor_)); } -} - -// =================================================================== - -void ImmutableMessageGenerator:: -GenerateCommonBuilderMethods(io::Printer* printer) { - if (HasDescriptorMethods(descriptor_)) { - 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.BuilderParent parent) {\n" - " super(parent);\n" - " maybeForceBuilderInitialization();\n" - "}\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_)); - } else { - // LITE runtime passes along the default instance to implement - // getDefaultInstanceForType() at the GeneratedMessageLite level. - printer->Print( - "// Construct using $classname$.newBuilder()\n" - "private Builder() {\n" - " super(defaultInstance);\n" - " maybeForceBuilderInitialization();\n" - "}\n" - "\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_)); + 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 (HasNestedBuilders(descriptor_)) { + if (!map_fields.empty()) { printer->Print( - "private void maybeForceBuilderInitialization() {\n" - " if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {\n"); - + "@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 < descriptor_->field_count(); i++) { - if (!descriptor_->field(i)->containing_oneof()) { - field_generators_.get(descriptor_->field(i)) - .GenerateFieldBuilderInitializationCode(printer); - } + 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", SimpleItoa(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"); - } else { printer->Print( - "private void maybeForceBuilderInitialization() {\n" - "}\n"); - } - - printer->Print( - "public Builder clear() {\n" - " super.clear();\n"); - - printer->Indent(); - - for (int i = 0; i < descriptor_->field_count(); i++) { - if (!descriptor_->field(i)->containing_oneof()) { - field_generators_.get(descriptor_->field(i)) - .GenerateBuilderClearCode(printer); - } - } - - for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { - printer->Print( - "$oneof_name$Case_ = 0;\n" - "$oneof_name$_ = null;\n", - "oneof_name", context_->GetOneofGeneratorInfo( - descriptor_->oneof_decl(i))->name); - } - - printer->Outdent(); - - printer->Print( - " return this;\n" - "}\n" - "\n"); - - if (HasDescriptorMethods(descriptor_)) { - printer->Print( - "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( - "public $classname$ getDefaultInstanceForType() {\n" - " return $classname$.getDefaultInstance();\n" - "}\n" - "\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_)); - } - - // ----------------------------------------------------------------- - - if (HasDescriptorMethods(descriptor_)) { - // LITE implements build in GeneratedMessageLite to save methods. - printer->Print( - "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_)); - } - - if (HasDescriptorMethods(descriptor_)) { - printer->Print( - "public $classname$ buildPartial() {\n" - " $classname$ result = new $classname$(this);\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_)); - } else { - // LITE_RUNTIME only provides a single message constructor. - printer->Print( - "public $classname$ buildPartial() {\n" - " $classname$ result = new $classname$(\n" - " com.google.protobuf.Internal\n" - " .EMPTY_CODED_INPUT_STREAM,\n" - " com.google.protobuf.ExtensionRegistryLite\n" - " .getEmptyRegistry());\n" - " result.unknownFields = this.unknownFields;\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_)); - - if (descriptor_->extension_range_count() > 0) { - printer->Print( - " result.extensions = this.buildExtensions();\n"); - } - } - - 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; - - if (GenerateHasBits(descriptor_)) { - // 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); - } - - if (GenerateHasBits(descriptor_)) { - // 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 (int i = 0; i < descriptor_->oneof_decl_count(); i++) { - printer->Print("result.$oneof_name$Case_ = $oneof_name$Case_;\n", - "oneof_name", context_->GetOneofGeneratorInfo( - descriptor_->oneof_decl(i))->name); - } - - printer->Outdent(); - - if (HasDescriptorMethods(descriptor_)) { - printer->Print( - " onBuilt();\n"); + " }\n" + "}\n"); } - printer->Print( - " return result;\n" + "protected com.google.protobuf.GeneratedMessage.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_)); - - // ----------------------------------------------------------------- - - if (HasGeneratedMethods(descriptor_)) { - // MergeFrom(Message other) requires the ability to distinguish the other - // messages type by its descriptor. - if (HasDescriptorMethods(descriptor_)) { - printer->Print( - "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 (!descriptor_->field(i)->containing_oneof()) { - field_generators_.get( - descriptor_->field(i)).GenerateMergingCode(printer); - } - } - - // Merge oneof fields. - for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) { - printer->Print( - "switch (other.get$oneof_capitalized_name$Case()) {\n", - "oneof_capitalized_name", - context_->GetOneofGeneratorInfo( - descriptor_->oneof_decl(i))->capitalized_name); - printer->Indent(); - for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { - const FieldDescriptor* field = descriptor_->oneof_decl(i)->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( - descriptor_->oneof_decl(i))->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"); - } - - if (PreserveUnknownFields(descriptor_)) { - printer->Print( - " this.mergeUnknownFields(other.unknownFields);\n"); - } - - if (HasDescriptorMethods(descriptor_)) { - printer->Print(" onChanged();\n"); - } - - printer->Print( - " return this;\n" - "}\n" - "\n"); - } -} - -// =================================================================== - -void ImmutableMessageGenerator:: -GenerateBuilderParsingMethods(io::Printer* printer) { - if (HasDescriptorMethods(descriptor_)) { - // LITE_RUNTIME implements this at the GeneratedMessageLite level. - printer->Print( - "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;\n" - " } finally {\n" - " if (parsedMessage != null) {\n" - " mergeFrom(parsedMessage);\n" - " }\n" - " }\n" - " return this;\n" - "}\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_)); - } + "classname", name_resolver_->GetImmutableClassName(descriptor_), + "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()), + "identifier", UniqueFileScopeIdentifier(descriptor_)); } // =================================================================== void ImmutableMessageGenerator::GenerateIsInitialized( - io::Printer* printer, UseMemoization useMemoization) { - // LITE_RUNTIME avoids generating isInitialized if it's not needed. - if (!HasDescriptorMethods(descriptor_) - && !HasRequiredFields(descriptor_)) { - return; - } - - bool memoization = useMemoization == MEMOIZE; - if (memoization) { - // 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"); - } + 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( "public final boolean isInitialized() {\n"); printer->Indent(); - if (memoization) { - // 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"); - } + // 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 @@ -1406,11 +818,10 @@ void ImmutableMessageGenerator::GenerateIsInitialized( if (field->is_required()) { printer->Print( "if (!has$name$()) {\n" - " $memoize$\n" + " memoizedIsInitialized = 0;\n" " return false;\n" "}\n", - "name", info->capitalized_name, - "memoize", memoization ? "memoizedIsInitialized = 0;" : ""); + "name", info->capitalized_name); } } @@ -1424,13 +835,12 @@ void ImmutableMessageGenerator::GenerateIsInitialized( case FieldDescriptor::LABEL_REQUIRED: printer->Print( "if (!get$name$().isInitialized()) {\n" - " $memoize$\n" + " memoizedIsInitialized = 0;\n" " return false;\n" "}\n", "type", name_resolver_->GetImmutableClassName( field->message_type()), - "name", info->capitalized_name, - "memoize", memoization ? "memoizedIsInitialized = 0;" : ""); + "name", info->capitalized_name); break; case FieldDescriptor::LABEL_OPTIONAL: if (!SupportFieldPresence(descriptor_->file()) && @@ -1449,38 +859,35 @@ void ImmutableMessageGenerator::GenerateIsInitialized( } printer->Print( " if (!get$name$().isInitialized()) {\n" - " $memoize$\n" + " memoizedIsInitialized = 0;\n" " return false;\n" " }\n" "}\n", - "name", info->capitalized_name, - "memoize", memoization ? "memoizedIsInitialized = 0;" : ""); + "name", info->capitalized_name); break; case FieldDescriptor::LABEL_REPEATED: if (IsMapEntry(field->message_type())) { printer->Print( "for ($type$ item : get$name$().values()) {\n" " if (!item.isInitialized()) {\n" - " $memoize$\n" + " memoizedIsInitialized = 0;\n" " return false;\n" " }\n" "}\n", "type", MapValueImmutableClassdName(field->message_type(), name_resolver_), - "name", info->capitalized_name, - "memoize", memoization ? "memoizedIsInitialized = 0;" : ""); + "name", info->capitalized_name); } else { printer->Print( "for (int i = 0; i < get$name$Count(); i++) {\n" " if (!get$name$(i).isInitialized()) {\n" - " $memoize$\n" + " memoizedIsInitialized = 0;\n" " return false;\n" " }\n" "}\n", "type", name_resolver_->GetImmutableClassName( field->message_type()), - "name", info->capitalized_name, - "memoize", memoization ? "memoizedIsInitialized = 0;" : ""); + "name", info->capitalized_name); } break; } @@ -1490,18 +897,15 @@ void ImmutableMessageGenerator::GenerateIsInitialized( if (descriptor_->extension_range_count() > 0) { printer->Print( "if (!extensionsAreInitialized()) {\n" - " $memoize$\n" + " memoizedIsInitialized = 0;\n" " return false;\n" - "}\n", - "memoize", memoization ? "memoizedIsInitialized = 0;" : ""); + "}\n"); } printer->Outdent(); - if (memoization) { - printer->Print( - " memoizedIsInitialized = 1;\n"); - } + printer->Print( + " memoizedIsInitialized = 1;\n"); printer->Print( " return true;\n" @@ -1567,12 +971,10 @@ GenerateEqualsAndHashCode(io::Printer* printer) { printer->Print( "result = result && unknownFields.equals(other.unknownFields);\n"); } - if (HasDescriptorMethods(descriptor_)) { - if (descriptor_->extension_range_count() > 0) { - printer->Print( - "result = result &&\n" - " getExtensionFields().equals(other.getExtensionFields());\n"); - } + if (descriptor_->extension_range_count() > 0) { + printer->Print( + "result = result &&\n" + " getExtensionFields().equals(other.getExtensionFields());\n"); } printer->Print( "return result;\n"); @@ -1595,14 +997,7 @@ GenerateEqualsAndHashCode(io::Printer* printer) { "}\n" "int hash = 41;\n"); - if (HasDescriptorMethods(descriptor_)) { - printer->Print("hash = (19 * hash) + getDescriptorForType().hashCode();\n"); - } else { - // Include the hash of the class so that two objects with different types - // but the same field values will probably have different hashes. - printer->Print("hash = (19 * hash) + $classname$.class.hashCode();\n", - "classname", name_resolver_->GetImmutableClassName(descriptor_)); - } + printer->Print("hash = (19 * hash) + getDescriptorForType().hashCode();\n"); for (int i = 0; i < descriptor_->field_count(); i++) { const FieldDescriptor* field = descriptor_->field(i); @@ -1620,11 +1015,9 @@ GenerateEqualsAndHashCode(io::Printer* printer) { printer->Print("}\n"); } } - if (HasDescriptorMethods(descriptor_)) { - if (descriptor_->extension_range_count() > 0) { - printer->Print( - "hash = hashFields(hash, getExtensionFields());\n"); - } + if (descriptor_->extension_range_count() > 0) { + printer->Print( + "hash = hashFields(hash, getExtensionFields());\n"); } printer->Print( @@ -1667,13 +1060,8 @@ GenerateParsingConstructor(io::Printer* printer) { printer->Indent(); // Initialize all fields to default. - if (HasDescriptorMethods(descriptor_)) { - printer->Print( - "this();\n"); - } else { - // LITE_RUNTIME only has one constructor. - GenerateInitializers(printer); - } + printer->Print( + "this();\n"); // Use builder bits to track mutable repeated fields. int totalBuilderBits = 0; @@ -1689,15 +1077,9 @@ GenerateParsingConstructor(io::Printer* printer) { } if (PreserveUnknownFields(descriptor_)) { - if (HasDescriptorMethods(descriptor_)) { - printer->Print( - "com.google.protobuf.UnknownFieldSet.Builder unknownFields =\n" - " com.google.protobuf.UnknownFieldSet.newBuilder();\n"); - } else { - printer->Print( - "com.google.protobuf.UnknownFieldSetLite.Builder unknownFields =\n" - " com.google.protobuf.UnknownFieldSetLite.newBuilder();\n"); - } + printer->Print( + "com.google.protobuf.UnknownFieldSet.Builder unknownFields =\n" + " com.google.protobuf.UnknownFieldSet.newBuilder();\n"); } printer->Print( @@ -1720,29 +1102,14 @@ GenerateParsingConstructor(io::Printer* printer) { " break;\n"); if (PreserveUnknownFields(descriptor_)) { - if (!HasDescriptorMethods(descriptor_) - && descriptor_->extension_range_count() > 0) { - // Lite runtime directly invokes parseUnknownField to reduce method - // counts. - printer->Print( - "default: {\n" - " if (!parseUnknownField(extensions, getDefaultInstanceForType(),\n" - " input, unknownFields,\n" - " extensionRegistry, tag)) {\n" - " done = true;\n" // it's an endgroup tag - " }\n" - " break;\n" - "}\n"); - } else { - printer->Print( - "default: {\n" - " if (!parseUnknownField(input, unknownFields,\n" - " extensionRegistry, tag)) {\n" - " done = true;\n" // it's an endgroup tag - " }\n" - " break;\n" - "}\n"); - } + printer->Print( + "default: {\n" + " if (!parseUnknownField(input, unknownFields,\n" + " extensionRegistry, tag)) {\n" + " done = true;\n" // it's an endgroup tag + " }\n" + " break;\n" + "}\n"); } else { printer->Print( "default: {\n" @@ -1817,18 +1184,9 @@ GenerateParsingConstructor(io::Printer* printer) { printer->Print("this.unknownFields = unknownFields.build();\n"); } - if (!HasDescriptorMethods(descriptor_)) { - // LITE runtime uses a static method to reduce method count. - if (descriptor_->extension_range_count() > 0) { - // Make extensions immutable. - printer->Print( - "makeExtensionsImmutable(extensions);\n"); - } - } else { - // Make extensions immutable. - printer->Print( - "makeExtensionsImmutable();\n"); - } + // Make extensions immutable. + printer->Print( + "makeExtensionsImmutable();\n"); printer->Outdent(); printer->Outdent(); @@ -1866,9 +1224,9 @@ void ImmutableMessageGenerator::GenerateParser(io::Printer* printer) { " }\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. + // 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" @@ -1878,7 +1236,8 @@ void ImmutableMessageGenerator::GenerateParser(io::Printer* printer) { " throw e.setUnfinishedMessage(builder.buildPartial());\n" "} catch (java.io.IOException e) {\n" " throw new com.google.protobuf.InvalidProtocolBufferException(\n" - " e.getMessage()).setUnfinishedMessage(builder.buildPartial());\n" + " e.getMessage()).setUnfinishedMessage(\n" + " builder.buildPartial());\n" "}\n" "return builder.buildPartial();\n"); printer->Outdent(); @@ -1890,16 +1249,13 @@ void ImmutableMessageGenerator::GenerateParser(io::Printer* printer) { "};\n" "\n"); - if (HasDescriptorMethods(descriptor_)) { - // LITE_RUNTIME implements this at the GeneratedMessageLite level. - printer->Print( - "@java.lang.Override\n" - "public com.google.protobuf.Parser<$classname$> getParserForType() {\n" - " return PARSER;\n" - "}\n" - "\n", - "classname", descriptor_->name()); - } + printer->Print( + "@java.lang.Override\n" + "public com.google.protobuf.Parser<$classname$> getParserForType() {\n" + " return PARSER;\n" + "}\n" + "\n", + "classname", descriptor_->name()); } // =================================================================== diff --git a/src/google/protobuf/compiler/java/java_message.h b/src/google/protobuf/compiler/java/java_message.h index 016fdd5d..c3c37765 100644 --- a/src/google/protobuf/compiler/java/java_message.h +++ b/src/google/protobuf/compiler/java/java_message.h @@ -67,8 +67,8 @@ class MessageGenerator { virtual void GenerateStaticVariables(io::Printer* printer) = 0; // Output code which initializes the static variables generated by - // GenerateStaticVariables(). - virtual void GenerateStaticVariableInitializers(io::Printer* printer) = 0; + // 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; @@ -97,16 +97,16 @@ class ImmutableMessageGenerator : public MessageGenerator { virtual void GenerateInterface(io::Printer* printer); virtual void GenerateExtensionRegistrationCode(io::Printer* printer); virtual void GenerateStaticVariables(io::Printer* printer); - virtual void GenerateStaticVariableInitializers(io::Printer* printer); + + // Returns an estimate of the number of bytes the printed code will compile to + virtual int GenerateStaticVariableInitializers(io::Printer* printer); private: - enum UseMemoization { - MEMOIZE, - DONT_MEMOIZE - }; void GenerateFieldAccessorTable(io::Printer* printer); - void GenerateFieldAccessorTableInitializer(io::Printer* printer); + + // 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); @@ -116,11 +116,8 @@ class ImmutableMessageGenerator : public MessageGenerator { io::Printer* printer, const Descriptor::ExtensionRange* range); void GenerateBuilder(io::Printer* printer); - void GenerateCommonBuilderMethods(io::Printer* printer); - void GenerateDescriptorMethods(io::Printer* printer, bool is_builder); - void GenerateBuilderParsingMethods(io::Printer* printer); - void GenerateIsInitialized(io::Printer* printer, - UseMemoization useMemoization); + 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); diff --git a/src/google/protobuf/compiler/java/java_message_builder.cc b/src/google/protobuf/compiler/java/java_message_builder.cc new file mode 100644 index 00000000..72694119 --- /dev/null +++ b/src/google/protobuf/compiler/java/java_message_builder.cc @@ -0,0 +1,661 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING 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 <google/protobuf/compiler/java/java_message_builder.h> + +#include <algorithm> +#include <google/protobuf/stubs/hash.h> +#include <map> +#include <memory> +#ifndef _SHARED_PTR_H +#include <google/protobuf/stubs/shared_ptr.h> +#endif +#include <vector> + +#include <google/protobuf/compiler/java/java_context.h> +#include <google/protobuf/compiler/java/java_doc_comment.h> +#include <google/protobuf/compiler/java/java_enum.h> +#include <google/protobuf/compiler/java/java_extension.h> +#include <google/protobuf/compiler/java/java_generator_factory.h> +#include <google/protobuf/compiler/java/java_helpers.h> +#include <google/protobuf/compiler/java/java_name_resolver.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/substitute.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +namespace { +bool GenerateHasBits(const Descriptor* descriptor) { + return SupportFieldPresence(descriptor->file()) || + HasRepeatedFields(descriptor); +} + +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_NE( + FileOptions::LITE_RUNTIME, descriptor->file()->options().optimize_for()); +} + +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.ExtendableBuilder<\n" + " $classname$, Builder> implements\n" + " $extra_interfaces$\n" + " $classname$OrBuilder {\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_), + "extra_interfaces", ExtraBuilderInterfaces(descriptor_)); + } else { + printer->Print( + "public static final class Builder extends\n" + " com.google.protobuf.GeneratedMessage.Builder<Builder> implements\n" + " $extra_interfaces$\n" + " $classname$OrBuilder {\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_), + "extra_interfaces", ExtraBuilderInterfaces(descriptor_)); + } + printer->Indent(); + + GenerateDescriptorMethods(printer); + GenerateCommonBuilderMethods(printer); + + if (HasGeneratedMethods(descriptor_)) { + GenerateIsInitialized(printer); + GenerateBuilderParsingMethods(printer); + } + + // oneof + map<string, string> vars; + for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { + vars["oneof_name"] = context_->GetOneofGeneratorInfo( + descriptor_->oneof_decl(i))->name; + vars["oneof_capitalized_name"] = context_->GetOneofGeneratorInfo( + descriptor_->oneof_decl(i))->capitalized_name; + vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->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.valueOf(\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"); + } + + if (GenerateHasBits(descriptor_)) { + // 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); + } + + if (!PreserveUnknownFields(descriptor_)) { + printer->Print( + "public final Builder setUnknownFields(\n" + " final com.google.protobuf.UnknownFieldSet unknownFields) {\n" + " return this;\n" + "}\n" + "\n" + "public final Builder mergeUnknownFields(\n" + " final com.google.protobuf.UnknownFieldSet unknownFields) {\n" + " return this;\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_)); + } + 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", SimpleItoa(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", SimpleItoa(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( + "protected com.google.protobuf.GeneratedMessage.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_)); +} + +// =================================================================== + +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.BuilderParent parent) {\n" + " super(parent);\n" + " maybeForceBuilderInitialization();\n" + "}\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + + printer->Print( + "private void maybeForceBuilderInitialization() {\n" + " if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {\n"); + + printer->Indent(); + printer->Indent(); + for (int i = 0; i < descriptor_->field_count(); i++) { + if (!descriptor_->field(i)->containing_oneof()) { + field_generators_.get(descriptor_->field(i)) + .GenerateFieldBuilderInitializationCode(printer); + } + } + printer->Outdent(); + printer->Outdent(); + + printer->Print( + " }\n" + "}\n"); + + printer->Print( + "public Builder clear() {\n" + " super.clear();\n"); + + printer->Indent(); + + for (int i = 0; i < descriptor_->field_count(); i++) { + if (!descriptor_->field(i)->containing_oneof()) { + field_generators_.get(descriptor_->field(i)) + .GenerateBuilderClearCode(printer); + } + } + + for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { + printer->Print( + "$oneof_name$Case_ = 0;\n" + "$oneof_name$_ = null;\n", + "oneof_name", context_->GetOneofGeneratorInfo( + descriptor_->oneof_decl(i))->name); + } + + printer->Outdent(); + + printer->Print( + " return this;\n" + "}\n" + "\n"); + + printer->Print( + "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( + "public $classname$ getDefaultInstanceForType() {\n" + " return $classname$.getDefaultInstance();\n" + "}\n" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + + printer->Print( + "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( + "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; + + if (GenerateHasBits(descriptor_)) { + // 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); + } + + if (GenerateHasBits(descriptor_)) { + // 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 (int i = 0; i < descriptor_->oneof_decl_count(); i++) { + printer->Print("result.$oneof_name$Case_ = $oneof_name$Case_;\n", + "oneof_name", context_->GetOneofGeneratorInfo( + descriptor_->oneof_decl(i))->name); + } + + printer->Outdent(); + + printer->Print( + " onBuilt();\n"); + + printer->Print( + " return result;\n" + "}\n" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + + // ----------------------------------------------------------------- + + if (HasGeneratedMethods(descriptor_)) { + printer->Print( + "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 (!descriptor_->field(i)->containing_oneof()) { + field_generators_.get( + descriptor_->field(i)).GenerateMergingCode(printer); + } + } + + // Merge oneof fields. + for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) { + printer->Print( + "switch (other.get$oneof_capitalized_name$Case()) {\n", + "oneof_capitalized_name", + context_->GetOneofGeneratorInfo( + descriptor_->oneof_decl(i))->capitalized_name); + printer->Indent(); + for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { + const FieldDescriptor* field = descriptor_->oneof_decl(i)->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( + descriptor_->oneof_decl(i))->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"); + } + + if (PreserveUnknownFields(descriptor_)) { + 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( + "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;\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( + "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: + if (!SupportFieldPresence(descriptor_->file()) && + field->containing_oneof() != NULL) { + const OneofDescriptor* oneof = field->containing_oneof(); + const OneofGeneratorInfo* oneof_info = + context_->GetOneofGeneratorInfo(oneof); + printer->Print( + "if ($oneof_name$Case_ == $field_number$) {\n", + "oneof_name", oneof_info->name, + "field_number", SimpleItoa(field->number())); + } else { + printer->Print( + "if (has$name$()) {\n", + "name", info->capitalized_name); + } + printer->Print( + " 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$().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/src/google/protobuf/compiler/java/java_message_builder.h b/src/google/protobuf/compiler/java/java_message_builder.h new file mode 100644 index 00000000..015ea062 --- /dev/null +++ b/src/google/protobuf/compiler/java/java_message_builder.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_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_BUILDER_H__ + +#include <string> +#include <map> +#include <google/protobuf/compiler/java/java_field.h> + +namespace google { +namespace protobuf { + namespace compiler { + namespace java { + class Context; // context.h + class ClassNameResolver; // name_resolver.h + } + } + namespace io { + class Printer; // printer.h + } +} + +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_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageBuilderGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_BUILDER_H__ diff --git a/src/google/protobuf/compiler/java/java_message_builder_lite.cc b/src/google/protobuf/compiler/java/java_message_builder_lite.cc new file mode 100644 index 00000000..8719d00d --- /dev/null +++ b/src/google/protobuf/compiler/java/java_message_builder_lite.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. + +// Author: dweis@google.com (Daniel Weis) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <google/protobuf/compiler/java/java_message_builder_lite.h> + +#include <algorithm> +#include <google/protobuf/stubs/hash.h> +#include <map> +#include <memory> +#ifndef _SHARED_PTR_H +#include <google/protobuf/stubs/shared_ptr.h> +#endif +#include <vector> + +#include <google/protobuf/compiler/java/java_context.h> +#include <google/protobuf/compiler/java/java_doc_comment.h> +#include <google/protobuf/compiler/java/java_enum.h> +#include <google/protobuf/compiler/java/java_extension.h> +#include <google/protobuf/compiler/java/java_generator_factory.h> +#include <google/protobuf/compiler/java/java_helpers.h> +#include <google/protobuf/compiler/java/java_name_resolver.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/substitute.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +namespace { +bool GenerateHasBits(const Descriptor* descriptor) { + return SupportFieldPresence(descriptor->file()) || + HasRepeatedFields(descriptor); +} + +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 + +MessageBuilderLiteGenerator::MessageBuilderLiteGenerator( + const Descriptor* descriptor, Context* context) + : descriptor_(descriptor), context_(context), + name_resolver_(context->GetNameResolver()), + field_generators_(descriptor, context_) { + GOOGLE_CHECK_EQ( + FileOptions::LITE_RUNTIME, descriptor->file()->options().optimize_for()); +} + +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 + map<string, string> vars; + for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { + vars["oneof_name"] = context_->GetOneofGeneratorInfo( + descriptor_->oneof_decl(i))->name; + vars["oneof_capitalized_name"] = context_->GetOneofGeneratorInfo( + descriptor_->oneof_decl(i))->capitalized_name; + vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index()); + + // oneofCase() and clearOneof() + printer->Print(vars, + "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"); + } + + if (GenerateHasBits(descriptor_)) { + // 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); + } + + if (!PreserveUnknownFields(descriptor_)) { + printer->Print( + "public final Builder setUnknownFields(\n" + " final com.google.protobuf.UnknownFieldSet unknownFields) {\n" + " return this;\n" + "}\n" + "\n" + "public final Builder mergeUnknownFields(\n" + " final com.google.protobuf.UnknownFieldSet unknownFields) {\n" + " return this;\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 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/src/google/protobuf/compiler/java/java_message_builder_lite.h b/src/google/protobuf/compiler/java/java_message_builder_lite.h new file mode 100644 index 00000000..8597b2e6 --- /dev/null +++ b/src/google/protobuf/compiler/java/java_message_builder_lite.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. + +// 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 <string> +#include <map> +#include <google/protobuf/compiler/java/java_field.h> + +namespace google { +namespace protobuf { + namespace compiler { + namespace java { + class Context; // context.h + class ClassNameResolver; // name_resolver.h + } + } + namespace io { + class Printer; // printer.h + } +} + +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_; + + 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/src/google/protobuf/compiler/java/java_message_field.cc b/src/google/protobuf/compiler/java/java_message_field.cc index a2d12a38..b180b4a7 100644 --- a/src/google/protobuf/compiler/java/java_message_field.cc +++ b/src/google/protobuf/compiler/java/java_message_field.cc @@ -157,11 +157,9 @@ GenerateInterfaceMembers(io::Printer* printer) const { printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n"); - if (HasNestedBuilders(descriptor_->containing_type())) { - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder();\n"); - } + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder();\n"); } void ImmutableMessageFieldGenerator:: @@ -182,14 +180,12 @@ GenerateMembers(io::Printer* printer) const { " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" "}\n"); - if (HasNestedBuilders(descriptor_->containing_type())) { - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public $type$OrBuilder " - "get$capitalized_name$OrBuilder() {\n" - " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" - "}\n"); - } + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$OrBuilder " + "get$capitalized_name$OrBuilder() {\n" + " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" + "}\n"); } else { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, @@ -202,14 +198,12 @@ GenerateMembers(io::Printer* printer) const { " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" "}\n"); - if (HasNestedBuilders(descriptor_->containing_type())) { - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public $type$OrBuilder " - "get$capitalized_name$OrBuilder() {\n" - " return get$capitalized_name$();\n" - "}\n"); - } + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$OrBuilder " + "get$capitalized_name$OrBuilder() {\n" + " return get$capitalized_name$();\n" + "}\n"); } } @@ -217,19 +211,15 @@ void ImmutableMessageFieldGenerator::PrintNestedBuilderCondition( io::Printer* printer, const char* regular_case, const char* nested_builder_case) const { - if (HasNestedBuilders(descriptor_->containing_type())) { - 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"); - } else { - printer->Print(variables_, regular_case); - } + 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( @@ -260,14 +250,12 @@ GenerateBuilderMembers(io::Printer* printer) const { printer->Print(variables_, "private $type$ $name$_ = null;\n"); - if (HasNestedBuilders(descriptor_->containing_type())) { - printer->Print(variables_, + printer->Print(variables_, // If this builder is non-null, it is used and the other fields are // ignored. "private com.google.protobuf.SingleFieldBuilder<\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". @@ -368,40 +356,38 @@ GenerateBuilderMembers(io::Printer* printer) const { "$clear_has_field_bit_builder$\n" "return this;\n"); - if (HasNestedBuilders(descriptor_->containing_type())) { - 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"); - 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"); - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "private com.google.protobuf.SingleFieldBuilder<\n" - " $type$, $type$.Builder, $type$OrBuilder> \n" - " get$capitalized_name$FieldBuilder() {\n" - " if ($name$Builder_ == null) {\n" - " $name$Builder_ = new com.google.protobuf.SingleFieldBuilder<\n" - " $type$, $type$.Builder, $type$OrBuilder>(\n" - " get$capitalized_name$(),\n" - " getParentForChildren(),\n" - " isClean());\n" - " $name$_ = null;\n" - " }\n" - " return $name$Builder_;\n" - "}\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"); + 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"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private com.google.protobuf.SingleFieldBuilder<\n" + " $type$, $type$.Builder, $type$OrBuilder> \n" + " get$capitalized_name$FieldBuilder() {\n" + " if ($name$Builder_ == null) {\n" + " $name$Builder_ = new com.google.protobuf.SingleFieldBuilder<\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:: @@ -557,16 +543,14 @@ GenerateMembers(io::Printer* printer) const { " return $type$.getDefaultInstance();\n" "}\n"); - if (HasNestedBuilders(descriptor_->containing_type())) { - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$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"); - } + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$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"); } void ImmutableMessageOneofFieldGenerator:: @@ -574,14 +558,12 @@ 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. - if (HasNestedBuilders(descriptor_->containing_type())) { - printer->Print(variables_, - // If this builder is non-null, it is used and the other fields are - // ignored. - "private com.google.protobuf.SingleFieldBuilder<\n" - " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;" - "\n"); - } + printer->Print(variables_, + // If this builder is non-null, it is used and the other fields are + // ignored. + "private com.google.protobuf.SingleFieldBuilder<\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". @@ -683,45 +665,43 @@ GenerateBuilderMembers(io::Printer* printer) const { "return this;\n"); - if (HasNestedBuilders(descriptor_->containing_type())) { - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$deprecation$public $type$.Builder get$capitalized_name$Builder() {\n" - " return get$capitalized_name$FieldBuilder().getBuilder();\n" - "}\n"); - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "$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"); - WriteFieldDocComment(printer, descriptor_); - printer->Print(variables_, - "private com.google.protobuf.SingleFieldBuilder<\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<\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"); - } + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$.Builder get$capitalized_name$Builder() {\n" + " return get$capitalized_name$FieldBuilder().getBuilder();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$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"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private com.google.protobuf.SingleFieldBuilder<\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<\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"); } void ImmutableMessageOneofFieldGenerator:: @@ -831,16 +811,15 @@ GenerateInterfaceMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); printer->Print(variables_, "$deprecation$int get$capitalized_name$Count();\n"); - if (HasNestedBuilders(descriptor_->containing_type())) { - 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"); - } + + 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:: @@ -882,19 +861,15 @@ void RepeatedImmutableMessageFieldGenerator::PrintNestedBuilderCondition( io::Printer* printer, const char* regular_case, const char* nested_builder_case) const { - if (HasNestedBuilders(descriptor_->containing_type())) { - 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"); - } else { - printer->Print(variables_, regular_case); - } + 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( @@ -942,14 +917,12 @@ GenerateBuilderMembers(io::Printer* printer) const { "}\n" "\n"); - if (HasNestedBuilders(descriptor_->containing_type())) { - printer->Print(variables_, - // If this builder is non-null, it is used and the other fields are - // ignored. - "private com.google.protobuf.RepeatedFieldBuilder<\n" - " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;\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<\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". @@ -1116,70 +1089,68 @@ GenerateBuilderMembers(io::Printer* printer) const { "return this;\n"); - if (HasNestedBuilders(descriptor_->containing_type())) { - 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"); + 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"); - 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"); + 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"); - 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"); + 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"); - 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"); - 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"); - 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<\n" - " $type$, $type$.Builder, $type$OrBuilder> \n" - " get$capitalized_name$FieldBuilder() {\n" - " if ($name$Builder_ == null) {\n" - " $name$Builder_ = new com.google.protobuf.RepeatedFieldBuilder<\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"); - } + 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"); + 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"); + 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<\n" + " $type$, $type$.Builder, $type$OrBuilder> \n" + " get$capitalized_name$FieldBuilder() {\n" + " if ($name$Builder_ == null) {\n" + " $name$Builder_ = new com.google.protobuf.RepeatedFieldBuilder<\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"); } void RepeatedImmutableMessageFieldGenerator:: diff --git a/src/google/protobuf/compiler/java/java_message_field_lite.cc b/src/google/protobuf/compiler/java/java_message_field_lite.cc new file mode 100644 index 00000000..8332202c --- /dev/null +++ b/src/google/protobuf/compiler/java/java_message_field_lite.cc @@ -0,0 +1,944 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 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 <google/protobuf/compiler/java/java_context.h> +#include <google/protobuf/compiler/java/java_message_field_lite.h> +#include <google/protobuf/compiler/java/java_doc_comment.h> +#include <google/protobuf/compiler/java/java_helpers.h> +#include <google/protobuf/compiler/java/java_name_resolver.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/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, + map<string, string>* variables) { + SetCommonFieldVariables(descriptor, info, variables); + + (*variables)["type"] = + name_resolver->GetImmutableClassName(descriptor->message_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)["on_changed"] = + HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : ""; + + if (SupportFieldPresence(descriptor->file())) { + // 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"; + } + + // For repeated builders, the underlying list tracks mutability state. + (*variables)["is_mutable"] = (*variables)["name"] + "_.isModifiable()"; + + (*variables)["get_has_field_bit_from_local"] = + GenerateGetBitFromLocal(builderBitIndex); + (*variables)["set_has_field_bit_to_local"] = + GenerateSetBitToLocal(messageBitIndex); +} + +} // namespace + +// =================================================================== + +ImmutableMessageFieldLiteGenerator:: +ImmutableMessageFieldLiteGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex, + Context* context) + : descriptor_(descriptor), messageBitIndex_(messageBitIndex), + builderBitIndex_(builderBitIndex), context_(context), + name_resolver_(context->GetNameResolver()) { + SetMessageVariables(descriptor, messageBitIndex, builderBitIndex, + context->GetFieldGeneratorInfo(descriptor), + name_resolver_, &variables_); +} + +ImmutableMessageFieldLiteGenerator::~ImmutableMessageFieldLiteGenerator() {} + +int ImmutableMessageFieldLiteGenerator::GetNumBitsForMessage() const { + return 1; +} + +int ImmutableMessageFieldLiteGenerator::GetNumBitsForBuilder() const { + return 0; +} + +void ImmutableMessageFieldLiteGenerator:: +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. + if (SupportFieldPresence(descriptor_->file()) || + descriptor_->containing_oneof() == NULL) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$boolean has$capitalized_name$();\n"); + } + WriteFieldDocComment(printer, descriptor_); + 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 (SupportFieldPresence(descriptor_->file())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $get_has_field_bit_message$;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$() {\n" + " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" + "}\n"); + } else { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $name$_ != null;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$() {\n" + " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" + "}\n"); + } + + // Field.Builder setField(Field value) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void set$capitalized_name$($type$ value) {\n" + " if (value == null) {\n" + " throw new NullPointerException();\n" + " }\n" + " $name$_ = value;\n" + " $set_has_field_bit_message$\n" + " }\n"); + + // Field.Builder setField(Field.Builder builderForValue) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void set$capitalized_name$(\n" + " $type$.Builder builderForValue) {\n" + " $name$_ = builderForValue.build();\n" + " $set_has_field_bit_message$\n" + "}\n"); + + // Field.Builder mergeField(Field value) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void merge$capitalized_name$($type$ value) {\n" + " 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_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return instance.has$capitalized_name$();\n" + "}\n"); + + // Field getField() + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$() {\n" + " return instance.get$capitalized_name$();\n" + "}\n"); + + // 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"); + + // 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);\n" + " return this;\n" + "}\n"); + + // 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"); + + // 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"); +} + +void ImmutableMessageFieldLiteGenerator:: +GenerateFieldBuilderInitializationCode(io::Printer* printer) const { + if (SupportFieldPresence(descriptor_->file())) { + printer->Print(variables_, + "get$capitalized_name$FieldBuilder();\n"); + } +} + + +void ImmutableMessageFieldLiteGenerator:: +GenerateInitializationCode(io::Printer* printer) const {} + +void ImmutableMessageFieldLiteGenerator:: +GenerateMergingCode(io::Printer* printer) const { + printer->Print(variables_, + "if (other.has$capitalized_name$()) {\n" + " merge$capitalized_name$(other.get$capitalized_name$());\n" + "}\n"); +} + +void ImmutableMessageFieldLiteGenerator:: +GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const { + // noop for scalars +} + +void ImmutableMessageFieldLiteGenerator:: +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$.PARSER,\n" + " extensionRegistry);\n"); + } else { + printer->Print(variables_, + "$name$_ = input.readMessage($type$.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 ImmutableMessageFieldLiteGenerator:: +GenerateParsingDoneCode(io::Printer* printer) const { + // noop for messages. +} + +void ImmutableMessageFieldLiteGenerator:: +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 ImmutableMessageFieldLiteGenerator:: +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 ImmutableMessageFieldLiteGenerator:: +GenerateEqualsCode(io::Printer* printer) const { + printer->Print(variables_, + "result = result && get$capitalized_name$()\n" + " .equals(other.get$capitalized_name$());\n"); +} + +void ImmutableMessageFieldLiteGenerator:: +GenerateHashCode(io::Printer* printer) const { + printer->Print(variables_, + "hash = (37 * hash) + $constant_name$;\n" + "hash = (53 * hash) + get$capitalized_name$().hashCode();\n"); +} + +string ImmutableMessageFieldLiteGenerator::GetBoxedType() const { + return name_resolver_->GetImmutableClassName(descriptor_->message_type()); +} + +// =================================================================== + +ImmutableMessageOneofFieldLiteGenerator:: +ImmutableMessageOneofFieldLiteGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex, + Context* context) + : ImmutableMessageFieldLiteGenerator( + descriptor, messageBitIndex, builderBitIndex, 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); + if (SupportFieldPresence(descriptor_->file())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $has_oneof_case_message$;\n" + "}\n"); + } + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$() {\n" + " if ($has_oneof_case_message$) {\n" + " return ($type$) $oneof_name$_;\n" + " }\n" + " return $type$.getDefaultInstance();\n" + "}\n"); + + // Field.Builder setField(Field value) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void set$capitalized_name$($type$ value) {\n" + " if (value == null) {\n" + " throw new NullPointerException();\n" + " }\n" + " $oneof_name$_ = value;\n" + " $set_oneof_case_message$;\n" + "}\n"); + + // Field.Builder setField(Field.Builder builderForValue) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void set$capitalized_name$(\n" + " $type$.Builder builderForValue) {\n" + " $oneof_name$_ = builderForValue.build();\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" + " 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:: +GenerateBuilderMembers(io::Printer* printer) const { + // The comments above the methods below are based on a hypothetical + // field of type "Field" called "Field". + + if (SupportFieldPresence(descriptor_->file())) { + // boolean hasField() + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return instance.has$capitalized_name$();\n" + "}\n"); + } + + // Field getField() + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$() {\n" + " return instance.get$capitalized_name$();\n" + "}\n"); + + // 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"); + + // 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);\n" + " return this;\n" + "}\n"); + + // 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"); + + // 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"); +} + +void ImmutableMessageOneofFieldLiteGenerator:: +GenerateMergingCode(io::Printer* printer) const { + printer->Print(variables_, + "merge$capitalized_name$(other.get$capitalized_name$());\n"); +} + +void ImmutableMessageOneofFieldLiteGenerator:: +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$.PARSER,\n" + " extensionRegistry);\n"); + } else { + printer->Print(variables_, + "$oneof_name$_ = input.readMessage($type$.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 ImmutableMessageOneofFieldLiteGenerator:: +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 ImmutableMessageOneofFieldLiteGenerator:: +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"); +} + +// =================================================================== + +RepeatedImmutableMessageFieldLiteGenerator:: +RepeatedImmutableMessageFieldLiteGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex, + Context* context) + : descriptor_(descriptor), messageBitIndex_(messageBitIndex), + builderBitIndex_(builderBitIndex), context_(context), + name_resolver_(context->GetNameResolver()) { + SetMessageVariables(descriptor, messageBitIndex, builderBitIndex, + context->GetFieldGeneratorInfo(descriptor), + name_resolver_, &variables_); +} + +RepeatedImmutableMessageFieldLiteGenerator:: +~RepeatedImmutableMessageFieldLiteGenerator() {} + +int RepeatedImmutableMessageFieldLiteGenerator::GetNumBitsForMessage() const { + return 0; +} + +int RepeatedImmutableMessageFieldLiteGenerator::GetNumBitsForBuilder() 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_, + "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n" + " return $name$_;\n" // note: unmodifiable list + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public java.util.List<? extends $type$OrBuilder> \n" + " get$capitalized_name$OrBuilderList() {\n" + " return $name$_;\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public int get$capitalized_name$Count() {\n" + " return $name$_.size();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + " return $name$_.get(index);\n" + "}\n"); + 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->Print(variables_, + "private void ensure$capitalized_name$IsMutable() {\n" + " if (!$is_mutable$) {\n" + " $name$_ = newProtobufList($name$_);\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" + " if (value == null) {\n" + " throw new NullPointerException();\n" + " }\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.set(index, value);\n" + "}\n"); + + // Builder setRepeatedField(int index, Field.Builder builderForValue) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void set$capitalized_name$(\n" + " int index, $type$.Builder builderForValue) {\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.set(index, builderForValue.build());\n" + "}\n"); + + // Builder addRepeatedField(Field value) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void add$capitalized_name$($type$ value) {\n" + " if (value == null) {\n" + " throw new NullPointerException();\n" + " }\n" + " 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" + " if (value == null) {\n" + " throw new NullPointerException();\n" + " }\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.add(index, value);\n" + "}\n"); + // Builder addRepeatedField(Field.Builder builderForValue) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void add$capitalized_name$(\n" + " $type$.Builder builderForValue) {\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.add(builderForValue.build());\n" + "}\n"); + + // Builder addRepeatedField(int index, Field.Builder builderForValue) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void add$capitalized_name$(\n" + " int index, $type$.Builder builderForValue) {\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.add(index, builderForValue.build());\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_, + "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n" + " return java.util.Collections.unmodifiableList(\n" + " instance.get$capitalized_name$List());\n" + "}\n"); + + // int getRepeatedFieldCount() + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public int get$capitalized_name$Count() {\n" + " return instance.get$capitalized_name$Count();\n" + "}"); + + // Field getRepeatedField(int index) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + " return instance.get$capitalized_name$(index);\n" + "}\n"); + + // 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"); + + // 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, builderForValue);\n" + " return this;\n" + "}\n"); + + // 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"); + + // 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"); + // 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);\n" + " return this;\n" + "}\n"); + + // 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, builderForValue);\n" + " return this;\n" + "}\n"); + + // 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"); + + // 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"); + + // 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"); +} + +void RepeatedImmutableMessageFieldLiteGenerator:: +GenerateFieldBuilderInitializationCode(io::Printer* printer) const { + printer->Print(variables_, + "get$capitalized_name$FieldBuilder();\n"); +} + +void RepeatedImmutableMessageFieldLiteGenerator:: +GenerateInitializationCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_ = emptyProtobufList();\n"); +} + +void RepeatedImmutableMessageFieldLiteGenerator:: +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. + printer->Print(variables_, + "if (!other.$name$_.isEmpty()) {\n" + " if ($name$_.isEmpty()) {\n" + " $name$_ = other.$name$_;\n" + " } else {\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.addAll(other.$name$_);\n" + " }\n" + " $on_changed$\n" + "}\n"); +} + +void RepeatedImmutableMessageFieldLiteGenerator:: +GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const { + printer->Print(variables_, + "$name$_.makeImmutable();\n"); +} + +void RepeatedImmutableMessageFieldLiteGenerator:: +GenerateParsingCode(io::Printer* printer) const { + printer->Print(variables_, + "if (!$is_mutable$) {\n" + " $name$_ = newProtobufList();\n" + "}\n"); + + if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) { + printer->Print(variables_, + "$name$_.add(input.readGroup($number$, $type$.PARSER,\n" + " extensionRegistry));\n"); + } else { + printer->Print(variables_, + "$name$_.add(input.readMessage($type$.PARSER, extensionRegistry));\n"); + } +} + +void RepeatedImmutableMessageFieldLiteGenerator:: +GenerateParsingDoneCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($is_mutable$) {\n" + " $name$_.makeImmutable();\n" + "}\n"); +} + +void RepeatedImmutableMessageFieldLiteGenerator:: +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 RepeatedImmutableMessageFieldLiteGenerator:: +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 RepeatedImmutableMessageFieldLiteGenerator:: +GenerateEqualsCode(io::Printer* printer) const { + printer->Print(variables_, + "result = result && get$capitalized_name$List()\n" + " .equals(other.get$capitalized_name$List());\n"); +} + +void RepeatedImmutableMessageFieldLiteGenerator:: +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"); +} + +string RepeatedImmutableMessageFieldLiteGenerator::GetBoxedType() const { + return name_resolver_->GetImmutableClassName(descriptor_->message_type()); +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/java/java_message_field_lite.h b/src/google/protobuf/compiler/java/java_message_field_lite.h new file mode 100644 index 00000000..ae26c06a --- /dev/null +++ b/src/google/protobuf/compiler/java/java_message_field_lite.h @@ -0,0 +1,157 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// 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 <map> +#include <string> +#include <google/protobuf/compiler/java/java_field.h> + +namespace google { +namespace protobuf { + namespace compiler { + namespace java { + class Context; // context.h + class ClassNameResolver; // name_resolver.h + } + } +} + +namespace protobuf { +namespace compiler { +namespace java { + +class ImmutableMessageFieldLiteGenerator : public ImmutableFieldLiteGenerator { + public: + explicit ImmutableMessageFieldLiteGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, + int builderBitIndex, Context* context); + ~ImmutableMessageFieldLiteGenerator(); + + // implements ImmutableFieldLiteGenerator ------------------------------------ + int GetNumBitsForMessage() const; + int GetNumBitsForBuilder() const; + void GenerateInterfaceMembers(io::Printer* printer) const; + void GenerateMembers(io::Printer* printer) const; + void GenerateBuilderMembers(io::Printer* printer) const; + void GenerateInitializationCode(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const; + void GenerateParsingCode(io::Printer* printer) const; + void GenerateParsingDoneCode(io::Printer* printer) const; + void GenerateSerializationCode(io::Printer* printer) const; + void GenerateSerializedSizeCode(io::Printer* printer) const; + void GenerateFieldBuilderInitializationCode(io::Printer* printer) const; + void GenerateEqualsCode(io::Printer* printer) const; + void GenerateHashCode(io::Printer* printer) const; + + string GetBoxedType() const; + + protected: + const FieldDescriptor* descriptor_; + map<string, string> variables_; + const int messageBitIndex_; + const int builderBitIndex_; + Context* context_; + ClassNameResolver* name_resolver_; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageFieldLiteGenerator); +}; + +class ImmutableMessageOneofFieldLiteGenerator + : public ImmutableMessageFieldLiteGenerator { + public: + ImmutableMessageOneofFieldLiteGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, + int builderBitIndex, Context* context); + ~ImmutableMessageOneofFieldLiteGenerator(); + + void GenerateMembers(io::Printer* printer) const; + void GenerateBuilderMembers(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateParsingCode(io::Printer* printer) const; + void GenerateSerializationCode(io::Printer* printer) const; + void GenerateSerializedSizeCode(io::Printer* printer) const; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageOneofFieldLiteGenerator); +}; + +class RepeatedImmutableMessageFieldLiteGenerator + : public ImmutableFieldLiteGenerator { + public: + explicit RepeatedImmutableMessageFieldLiteGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, + int builderBitIndex, Context* context); + ~RepeatedImmutableMessageFieldLiteGenerator(); + + // implements ImmutableFieldLiteGenerator ------------------------------------ + int GetNumBitsForMessage() const; + int GetNumBitsForBuilder() const; + void GenerateInterfaceMembers(io::Printer* printer) const; + void GenerateMembers(io::Printer* printer) const; + void GenerateBuilderMembers(io::Printer* printer) const; + void GenerateInitializationCode(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const; + void GenerateParsingCode(io::Printer* printer) const; + void GenerateParsingDoneCode(io::Printer* printer) const; + void GenerateSerializationCode(io::Printer* printer) const; + void GenerateSerializedSizeCode(io::Printer* printer) const; + void GenerateFieldBuilderInitializationCode(io::Printer* printer) const; + void GenerateEqualsCode(io::Printer* printer) const; + void GenerateHashCode(io::Printer* printer) const; + + string GetBoxedType() const; + + protected: + const FieldDescriptor* descriptor_; + map<string, string> variables_; + const int messageBitIndex_; + const int builderBitIndex_; + Context* context_; + 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/src/google/protobuf/compiler/java/java_message_lite.cc b/src/google/protobuf/compiler/java/java_message_lite.cc new file mode 100644 index 00000000..3accee92 --- /dev/null +++ b/src/google/protobuf/compiler/java/java_message_lite.cc @@ -0,0 +1,1174 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING 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 <google/protobuf/compiler/java/java_message_lite.h> + +#include <algorithm> +#include <google/protobuf/stubs/hash.h> +#include <map> +#include <memory> +#ifndef _SHARED_PTR_H +#include <google/protobuf/stubs/shared_ptr.h> +#endif +#include <vector> + +#include <google/protobuf/compiler/java/java_context.h> +#include <google/protobuf/compiler/java/java_doc_comment.h> +#include <google/protobuf/compiler/java/java_enum.h> +#include <google/protobuf/compiler/java/java_extension.h> +#include <google/protobuf/compiler/java/java_generator_factory.h> +#include <google/protobuf/compiler/java/java_helpers.h> +#include <google/protobuf/compiler/java/java_message_builder.h> +#include <google/protobuf/compiler/java/java_message_builder_lite.h> +#include <google/protobuf/compiler/java/java_name_resolver.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/substitute.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +using internal::WireFormat; +using internal::WireFormatLite; + +namespace { +bool GenerateHasBits(const Descriptor* descriptor) { + return SupportFieldPresence(descriptor->file()) || + HasRepeatedFields(descriptor); +} + +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 + +// =================================================================== +ImmutableMessageLiteGenerator::ImmutableMessageLiteGenerator( + const Descriptor* descriptor, Context* context) + : MessageGenerator(descriptor), context_(context), + name_resolver_(context->GetNameResolver()), + field_generators_(descriptor, context_) { + GOOGLE_CHECK_EQ( + FileOptions::LITE_RUNTIME, descriptor->file()->options().optimize_for()); +} + +ImmutableMessageLiteGenerator::~ImmutableMessageLiteGenerator() {} + +void ImmutableMessageLiteGenerator::GenerateStaticVariables( + io::Printer* printer) { + // 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); + } +} + +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) { + if (descriptor_->extension_range_count() > 0) { + printer->Print( + "public interface $classname$OrBuilder extends \n" + " $extra_interfaces$\n" + " com.google.protobuf.GeneratedMessageLite.\n" + " ExtendableMessageOrBuilder<\n" + " $classname$, $classname$.Builder> {\n", + "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), + "classname", descriptor_->name()); + } else { + printer->Print( + "public interface $classname$OrBuilder extends\n" + " $extra_interfaces$\n" + " com.google.protobuf.MessageLiteOrBuilder {\n", + "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), + "classname", descriptor_->name()); + } + + printer->Indent(); + for (int i = 0; i < descriptor_->field_count(); i++) { + printer->Print("\n"); + field_generators_.get(descriptor_->field(i)) + .GenerateInterfaceMembers(printer); + } + printer->Outdent(); + + printer->Print("}\n"); +} + +// =================================================================== + +void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { + bool is_own_file = + descriptor_->containing_type() == NULL && + MultipleJavaFiles(descriptor_->file(), /* immutable = */ true); + + map<string, string> variables; + variables["static"] = is_own_file ? " " : " static "; + variables["classname"] = descriptor_->name(); + variables["extra_interfaces"] = ExtraMessageInterfaces(descriptor_); + + WriteMessageDocComment(printer, descriptor_); + + // The builder_type stores the super type name of the nested Builder class. + string builder_type; + if (descriptor_->extension_range_count() > 0) { + printer->Print(variables, + "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, + "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(); + + GenerateParsingConstructor(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; + ImmutableMessageLiteGenerator messageGenerator( + descriptor_->nested_type(i), context_); + messageGenerator.GenerateInterface(printer); + messageGenerator.Generate(printer); + } + + if (GenerateHasBits(descriptor_)) { + // 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 + map<string, string> vars; + for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { + vars["oneof_name"] = context_->GetOneofGeneratorInfo( + descriptor_->oneof_decl(i))->name; + vars["oneof_capitalized_name"] = context_->GetOneofGeneratorInfo( + descriptor_->oneof_decl(i))->capitalized_name; + vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->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" + " implements com.google.protobuf.Internal.EnumLite {\n"); + printer->Indent(); + for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { + const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); + printer->Print( + "$field_name$($field_number$),\n", + "field_name", + ToUpper(field->name()), + "field_number", + SimpleItoa(field->number())); + } + printer->Print( + "$cap_oneof_name$_NOT_SET(0);\n", + "cap_oneof_name", + ToUpper(vars["oneof_name"])); + printer->Print(vars, + "private int value = 0;\n" + "private $oneof_capitalized_name$Case(int value) {\n" + " this.value = value;\n" + "}\n"); + printer->Print(vars, + "public static $oneof_capitalized_name$Case valueOf(int value) {\n" + " switch (value) {\n"); + for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { + const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); + printer->Print( + " case $field_number$: return $field_name$;\n", + "field_number", + SimpleItoa(field->number()), + "field_name", + ToUpper(field->name())); + } + printer->Print( + " case 0: return $cap_oneof_name$_NOT_SET;\n" + " default: throw new java.lang.IllegalArgumentException(\n" + " \"Value is undefined for this oneof enum.\");\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.valueOf(\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", SimpleItoa(descriptor_->field(i)->number())); + field_generators_.get(descriptor_->field(i)).GenerateMembers(printer); + printer->Print("\n"); + } + + GenerateMessageSerializationMethods(printer); + + if (HasEqualsAndHashCode(descriptor_)) { + GenerateEqualsAndHashCode(printer); + } + + + GenerateParseFromMethods(printer); + GenerateBuilder(printer); + + if (HasRequiredFields(descriptor_)) { + // 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( + "protected final Object dynamicMethod(\n" + " com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n" + " Object... args) {\n" + " switch (method) {\n" + " case PARSE_PARTIAL_FROM: {\n" + " return new $classname$(" + " (com.google.protobuf.CodedInputStream) args[0],\n" + " (com.google.protobuf.ExtensionRegistryLite) args[1]);\n" + " }\n" + " case NEW_INSTANCE: {\n" + " return new $classname$(\n" + " com.google.protobuf.Internal.EMPTY_CODED_INPUT_STREAM,\n" + " com.google.protobuf.ExtensionRegistryLite\n" + " .getEmptyRegistry());\n" + " }\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + + printer->Indent(); + printer->Indent(); + + printer->Print( + "case IS_INITIALIZED: {\n"); + printer->Indent(); + GenerateDynamicMethodIsInitialized(printer); + printer->Outdent(); + + printer->Print( + "}\n" + "case MAKE_IMMUTABLE: {\n"); + + printer->Indent(); + GenerateDynamicMethodMakeImmutable(printer); + printer->Outdent(); + + printer->Print( + "}\n" + "case NEW_BUILDER: {\n"); + + printer->Indent(); + GenerateDynamicMethodNewBuilder(printer); + printer->Outdent(); + + printer->Print( + "}\n" + "case MERGE_FROM: {\n"); + + printer->Indent(); + GenerateDynamicMethodMergeFrom(printer); + printer->Outdent(); + + printer->Print( + "}\n"); + + printer->Outdent(); + 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" + " DEFAULT_INSTANCE = new $classname$(\n" + " com.google.protobuf.Internal\n" + " .EMPTY_CODED_INPUT_STREAM,\n" + " com.google.protobuf.ExtensionRegistryLite\n" + " .getEmptyRegistry());\n" + "}\n" + "\n", + "classname", descriptor_->name()); + printer->Print( + "public static $classname$ getDefaultInstance() {\n" + " return DEFAULT_INSTANCE;\n" + "}\n" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + + GenerateParser(printer); + + // LITE_RUNTIME uses this to implement the *ForType methods at the + // GeneratedMessageLite level. + printer->Print( + "static {\n" + " com.google.protobuf.GeneratedMessageLite.onLoad(\n" + " $classname$.class, new com.google.protobuf.GeneratedMessageLite\n" + " .PrototypeHolder<$classname$, Builder>(\n" + " DEFAULT_INSTANCE, PARSER));" + "}\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 ImmutableMessageLiteGenerator:: +GenerateMessageSerializationMethods(io::Printer* printer) { + google::protobuf::scoped_array<const FieldDescriptor * > sorted_fields( + SortFieldsByNumber(descriptor_)); + + vector<const Descriptor::ExtensionRange*> sorted_extensions; + 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( + "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.GeneratedMessageLite\n" + " .ExtendableMessage<$classname$, $classname$.Builder>\n" + " .ExtensionWriter extensionWriter =\n" + " newMessageSetExtensionWriter();\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + } else { + printer->Print( + "com.google.protobuf.GeneratedMessageLite\n" + " .ExtendableMessage<$classname$, $classname$.Builder>\n" + " .ExtensionWriter extensionWriter =\n" + " newExtensionWriter();\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + } + } + + // 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 (PreserveUnknownFields(descriptor_)) { + printer->Print( + "unknownFields.writeTo(output);\n"); + } + + printer->Outdent(); + printer->Print( + "}\n" + "\n" + "public int getSerializedSize() {\n" + " int size = memoizedSerializedSize;\n" + " if (size != -1) return size;\n" + "\n" + " size = 0;\n"); + printer->Indent(); + + 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 (PreserveUnknownFields(descriptor_)) { + printer->Print( + "size += unknownFields.getSerializedSize();\n"); + } + + printer->Outdent(); + printer->Print( + " memoizedSerializedSize = size;\n" + " return size;\n" + "}\n" + "\n"); + + printer->Print( + "private static final long serialVersionUID = 0L;\n"); +} + +void ImmutableMessageLiteGenerator:: +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" + " 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 PARSER.parseFrom(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 PARSER.parseFrom(input, extensionRegistry);\n" + "}\n" + "public static $classname$ parseDelimitedFrom(java.io.InputStream input)\n" + " throws java.io.IOException {\n" + " return PARSER.parseDelimitedFrom(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 PARSER.parseDelimitedFrom(input, extensionRegistry);\n" + "}\n" + "public static $classname$ parseFrom(\n" + " com.google.protobuf.CodedInputStream input)\n" + " throws java.io.IOException {\n" + " return PARSER.parseFrom(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 PARSER.parseFrom(input, extensionRegistry);\n" + "}\n" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); +} + +void ImmutableMessageLiteGenerator::GenerateSerializeOneField( + io::Printer* printer, const FieldDescriptor* field) { + field_generators_.get(field).GenerateSerializationCode(printer); +} + +void ImmutableMessageLiteGenerator::GenerateSerializeOneExtensionRange( + io::Printer* printer, const Descriptor::ExtensionRange* range) { + printer->Print( + "extensionWriter.writeUntil($end$, output);\n", + "end", SimpleItoa(range->end)); +} + +// =================================================================== + +void ImmutableMessageLiteGenerator::GenerateBuilder(io::Printer* printer) { + 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" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + + MessageBuilderLiteGenerator builderGenerator(descriptor_, context_); + builderGenerator.Generate(printer); +} + +// =================================================================== + +void ImmutableMessageLiteGenerator::GenerateDynamicMethodIsInitialized( + io::Printer* printer) { + // Returns null for false, DEFAULT_INSTANCE for true. + if (!HasRequiredFields(descriptor_)) { + printer->Print("return DEFAULT_INSTANCE;\n"); + return; + } + + // Don't directly compare to -1 to avoid an Android x86 JIT bug. + printer->Print( + "byte isInitialized = memoizedIsInitialized;\n" + "if (isInitialized == 1) return DEFAULT_INSTANCE;\n" + "if (isInitialized == 0) return null;\n" + "\n" + "boolean shouldMemoize = ((Boolean) args[0]).booleanValue();\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" + " if (shouldMemoize) {\n" + " memoizedIsInitialized = 0;\n" + " }\n" + " return null;\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" + " if (shouldMemoize) {\n" + " memoizedIsInitialized = 0;\n" + " }\n" + " return null;\n" + "}\n", + "type", name_resolver_->GetImmutableClassName( + field->message_type()), + "name", info->capitalized_name); + break; + case FieldDescriptor::LABEL_OPTIONAL: + if (!SupportFieldPresence(descriptor_->file()) && + field->containing_oneof() != NULL) { + const OneofDescriptor* oneof = field->containing_oneof(); + const OneofGeneratorInfo* oneof_info = + context_->GetOneofGeneratorInfo(oneof); + printer->Print( + "if ($oneof_name$Case_ == $field_number$) {\n", + "oneof_name", oneof_info->name, + "field_number", SimpleItoa(field->number())); + } else { + printer->Print( + "if (has$name$()) {\n", + "name", info->capitalized_name); + } + printer->Print( + " if (!get$name$().isInitialized()) {\n" + " if (shouldMemoize) {\n" + " memoizedIsInitialized = 0;\n" + " }\n" + " return null;\n" + " }\n" + "}\n", + "name", info->capitalized_name); + break; + case FieldDescriptor::LABEL_REPEATED: + if (IsMapEntry(field->message_type())) { + printer->Print( + "for ($type$ item : get$name$().values()) {\n" + " if (!item.isInitialized()) {\n" + " if (shouldMemoize) {\n" + " memoizedIsInitialized = 0;\n" + " }\n" + " return null;\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" + " if (shouldMemoize) {\n" + " memoizedIsInitialized = 0;\n" + " }\n" + " return null;\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" + " if (shouldMemoize) {\n" + " memoizedIsInitialized = 0;\n" + " }\n" + " return null;\n" + "}\n"); + } + + printer->Print( + "if (shouldMemoize) memoizedIsInitialized = 1;\n"); + + printer->Print( + "return DEFAULT_INSTANCE;\n" + "\n"); +} + +// =================================================================== + +void ImmutableMessageLiteGenerator::GenerateDynamicMethodMakeImmutable( + io::Printer* printer) { + // Output generation code for each field. + for (int i = 0; i < descriptor_->field_count(); i++) { + field_generators_.get(descriptor_->field(i)) + .GenerateDynamicMethodMakeImmutableCode(printer); + } + printer->Print( + "return null;"); +} + +// =================================================================== + +void ImmutableMessageLiteGenerator::GenerateDynamicMethodNewBuilder( + io::Printer* printer) { + printer->Print( + "return new Builder();"); +} + +// =================================================================== + +void ImmutableMessageLiteGenerator::GenerateDynamicMethodMergeFrom( + io::Printer* printer) { + printer->Print( + // Optimization: If other is the default instance, we know none of its + // fields are set so we can skip the merge. + "Object arg = args[0];\n" + "if (arg == $classname$.getDefaultInstance()) return this;\n" + "$classname$ other = ($classname$) arg;\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + + for (int i = 0; i < descriptor_->field_count(); i++) { + if (!descriptor_->field(i)->containing_oneof()) { + field_generators_.get( + descriptor_->field(i)).GenerateMergingCode(printer); + } + } + + // Merge oneof fields. + for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) { + printer->Print( + "switch (other.get$oneof_capitalized_name$Case()) {\n", + "oneof_capitalized_name", + context_->GetOneofGeneratorInfo( + descriptor_->oneof_decl(i))->capitalized_name); + printer->Indent(); + for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { + const FieldDescriptor* field = descriptor_->oneof_decl(i)->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( + descriptor_->oneof_decl(i))->name)); + printer->Outdent(); + printer->Print( + "}\n"); + } + + // if message type has extensions + if (descriptor_->extension_range_count() > 0) { + printer->Print( + "this.mergeExtensionFields(other);\n"); + } + + if (PreserveUnknownFields(descriptor_)) { + printer->Print( + "this.mergeUnknownFields(other.unknownFields);\n"); + } + + printer->Print( + "return this;\n"); +} + +// =================================================================== + +namespace { +bool CheckHasBitsForEqualsAndHashCode(const FieldDescriptor* field) { + if (field->is_repeated()) { + return false; + } + if (SupportFieldPresence(field->file())) { + return true; + } + return GetJavaType(field) == JAVATYPE_MESSAGE && + field->containing_oneof() == NULL; +} +} // namespace + +void ImmutableMessageLiteGenerator:: +GenerateEqualsAndHashCode(io::Printer* printer) { + printer->Print( + "@java.lang.Override\n" + "public boolean equals(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_)); + + printer->Print("boolean result = true;\n"); + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field); + bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field); + if (check_has_bits) { + printer->Print( + "result = result && (has$name$() == other.has$name$());\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"); + } + } + if (PreserveUnknownFields(descriptor_)) { + // 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( + "result = result && unknownFields.equals(other.unknownFields);\n"); + } + printer->Print( + "return result;\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"); + + // Include the hash of the class so that two objects with different types + // but the same field values will probably have different hashes. + printer->Print("hash = (19 * hash) + $classname$.class.hashCode();\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + 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"); + } + } + + printer->Print( + "hash = (29 * hash) + unknownFields.hashCode();\n"); + printer->Print( + "memoizedHashCode = hash;\n" + "return hash;\n"); + printer->Outdent(); + printer->Print( + "}\n" + "\n"); +} + +// =================================================================== + +void ImmutableMessageLiteGenerator:: +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++) { + ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_) + .GenerateExtensionRegistrationCode(printer); + } +} + +// =================================================================== +void ImmutableMessageLiteGenerator:: +GenerateParsingConstructor(io::Printer* printer) { + google::protobuf::scoped_array<const FieldDescriptor * > sorted_fields( + SortFieldsByNumber(descriptor_)); + + printer->Print( + "private $classname$(\n" + " com.google.protobuf.CodedInputStream input,\n" + " com.google.protobuf.ExtensionRegistryLite extensionRegistry) {\n", + "classname", descriptor_->name()); + printer->Indent(); + + // Initialize all fields to default. + GenerateInitializers(printer); + + // Use builder bits to track mutable repeated fields. + int totalBuilderBits = 0; + for (int i = 0; i < descriptor_->field_count(); i++) { + const ImmutableFieldLiteGenerator& 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)); + } + + if (PreserveUnknownFields(descriptor_)) { + printer->Print( + "com.google.protobuf.UnknownFieldSetLite.Builder unknownFields =\n" + " com.google.protobuf.UnknownFieldSetLite.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"); + + if (PreserveUnknownFields(descriptor_)) { + if (descriptor_->extension_range_count() > 0) { + // Lite runtime directly invokes parseUnknownField to reduce method + // counts. + printer->Print( + "default: {\n" + " if (!parseUnknownField(extensions, getDefaultInstanceForType(),\n" + " input, unknownFields,\n" + " extensionRegistry, tag)) {\n" + " done = true;\n" // it's an endgroup tag + " }\n" + " break;\n" + "}\n"); + } else { + printer->Print( + "default: {\n" + " if (!parseUnknownField(input, unknownFields,\n" + " extensionRegistry, tag)) {\n" + " done = true;\n" // it's an endgroup tag + " }\n" + " break;\n" + "}\n"); + } + } else { + printer->Print( + "default: {\n" + " if (!input.skipField(tag)) {\n" + " done = true;\n" // it's an endgroup tag + " }\n" + " break;\n" + "}\n"); + } + + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = sorted_fields[i]; + uint32 tag = WireFormatLite::MakeTag(field->number(), + WireFormat::WireTypeForFieldType(field->type())); + + printer->Print( + "case $tag$: {\n", + "tag", SimpleItoa(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 packed_tag = WireFormatLite::MakeTag(field->number(), + WireFormatLite::WIRETYPE_LENGTH_DELIMITED); + printer->Print( + "case $tag$: {\n", + "tag", SimpleItoa(packed_tag)); + printer->Indent(); + + field_generators_.get(field).GenerateParsingCodeFromPacked(printer); + + printer->Outdent(); + printer->Print( + " 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 new RuntimeException(e.setUnfinishedMessage(this));\n" + "} catch (java.io.IOException e) {\n" + " throw new RuntimeException(\n" + " new com.google.protobuf.InvalidProtocolBufferException(\n" + " e.getMessage()).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); + } + + if (PreserveUnknownFields(descriptor_)) { + // Make unknown fields immutable. + printer->Print("this.unknownFields = unknownFields.build();\n"); + } + + if (descriptor_->extension_range_count() > 0) { + // Make extensions immutable. + printer->Print( + "makeExtensionsImmutable(extensions);\n"); + } + + printer->Outdent(); + printer->Outdent(); + printer->Print( + " }\n" // finally + "}\n"); +} + +// =================================================================== +void ImmutableMessageLiteGenerator::GenerateParser(io::Printer* printer) { + printer->Print( + "public static final com.google.protobuf.Parser<$classname$> PARSER =\n" + " new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n" + "\n", + "classname", descriptor_->name()); +} + +// =================================================================== +void ImmutableMessageLiteGenerator::GenerateInitializers(io::Printer* printer) { + for (int i = 0; i < descriptor_->field_count(); i++) { + if (!descriptor_->field(i)->containing_oneof()) { + field_generators_.get(descriptor_->field(i)) + .GenerateInitializationCode(printer); + } + } +} + + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/java/java_message_lite.h b/src/google/protobuf/compiler/java/java_message_lite.h new file mode 100644 index 00000000..2bd3cdd4 --- /dev/null +++ b/src/google/protobuf/compiler/java/java_message_lite.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: 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 <string> +#include <map> +#include <google/protobuf/compiler/java/java_field.h> +#include <google/protobuf/compiler/java/java_message.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +class ImmutableMessageLiteGenerator : public MessageGenerator { + public: + explicit ImmutableMessageLiteGenerator(const Descriptor* descriptor, + Context* context); + virtual ~ImmutableMessageLiteGenerator(); + + virtual void Generate(io::Printer* printer); + virtual void GenerateInterface(io::Printer* printer); + virtual void GenerateExtensionRegistrationCode(io::Printer* printer); + virtual void GenerateStaticVariables(io::Printer* printer); + virtual int GenerateStaticVariableInitializers(io::Printer* printer); + + private: + + 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 GenerateDynamicMethodIsInitialized(io::Printer* printer); + void GenerateDynamicMethodMakeImmutable(io::Printer* printer); + void GenerateDynamicMethodMergeFrom(io::Printer* printer); + void GenerateDynamicMethodNewBuilder(io::Printer* printer); + void GenerateInitializers(io::Printer* printer); + void GenerateEqualsAndHashCode(io::Printer* printer); + void GenerateParser(io::Printer* printer); + void GenerateParsingConstructor(io::Printer* printer); + + 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/src/google/protobuf/compiler/java/java_primitive_field.cc b/src/google/protobuf/compiler/java/java_primitive_field.cc index 48757c60..7bebe12a 100644 --- a/src/google/protobuf/compiler/java/java_primitive_field.cc +++ b/src/google/protobuf/compiler/java/java_primitive_field.cc @@ -74,7 +74,12 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, "" : ("= " + ImmutableDefaultValue(descriptor, name_resolver)); (*variables)["capitalized_type"] = GetCapitalizedType(descriptor, /* immutable = */ true); - (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor)); + if (descriptor->is_packed()) { + (*variables)["tag"] = SimpleItoa(WireFormatLite::MakeTag( + descriptor->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED)); + } else { + (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor)); + } (*variables)["tag_size"] = SimpleItoa( WireFormat::TagSize(descriptor->number(), GetType(descriptor))); if (IsReferenceType(GetJavaType(descriptor))) { @@ -599,7 +604,7 @@ GenerateMembers(io::Printer* printer) const { " return $name$_.get(index);\n" "}\n"); - if (descriptor_->options().packed() && + if (descriptor_->is_packed() && HasGeneratedMethods(descriptor_->containing_type())) { printer->Print(variables_, "private int $name$MemoizedSerializedSize = -1;\n"); @@ -771,7 +776,7 @@ GenerateParsingDoneCode(io::Printer* printer) const { void RepeatedImmutablePrimitiveFieldGenerator:: GenerateSerializationCode(io::Printer* printer) const { - if (descriptor_->options().packed()) { + 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. @@ -812,7 +817,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const { printer->Print( "size += dataSize;\n"); - if (descriptor_->options().packed()) { + if (descriptor_->is_packed()) { printer->Print(variables_, "if (!get$capitalized_name$List().isEmpty()) {\n" " size += $tag_size$;\n" @@ -825,7 +830,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const { } // cache the data size for packed fields. - if (descriptor_->options().packed()) { + if (descriptor_->is_packed()) { printer->Print(variables_, "$name$MemoizedSerializedSize = dataSize;\n"); } diff --git a/src/google/protobuf/compiler/java/java_primitive_field_lite.cc b/src/google/protobuf/compiler/java/java_primitive_field_lite.cc new file mode 100644 index 00000000..217ff9b6 --- /dev/null +++ b/src/google/protobuf/compiler/java/java_primitive_field_lite.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 <map> +#include <string> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/compiler/java/java_context.h> +#include <google/protobuf/compiler/java/java_doc_comment.h> +#include <google/protobuf/compiler/java/java_helpers.h> +#include <google/protobuf/compiler/java/java_name_resolver.h> +#include <google/protobuf/compiler/java/java_primitive_field_lite.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/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, + map<string, string>* variables) { + SetCommonFieldVariables(descriptor, info, variables); + + (*variables)["type"] = PrimitiveTypeName(GetJavaType(descriptor)); + (*variables)["boxed_type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor)); + (*variables)["field_type"] = (*variables)["type"]; + (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver); + (*variables)["default_init"] = IsDefaultValueJavaDefault(descriptor) ? + "" : ("= " + ImmutableDefaultValue(descriptor, name_resolver)); + (*variables)["capitalized_type"] = + GetCapitalizedType(descriptor, /* immutable = */ true); + (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor)); + (*variables)["tag_size"] = SimpleItoa( + WireFormat::TagSize(descriptor->number(), GetType(descriptor))); + + string capitalized_type = UnderscoresToCamelCase(PrimitiveTypeName( + GetJavaType(descriptor)), true /* cap_next_letter */); + switch (GetJavaType(descriptor)) { + 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)["new_list"] = "new" + capitalized_type + "List"; + (*variables)["empty_list"] = "empty" + capitalized_type + "List()"; + (*variables)["make_name_unmodifiable"] = + (*variables)["name"] + "_.makeImmutable()"; + (*variables)["repeated_index_get"] = + (*variables)["name"] + "_.get" + capitalized_type + "(index)"; + (*variables)["repeated_add"] = + (*variables)["name"] + "_.add" + capitalized_type; + (*variables)["repeated_set"] = + (*variables)["name"] + "_.set" + capitalized_type; + break; + default: + (*variables)["field_list_type"] = + "com.google.protobuf.Internal.ProtobufList<" + + (*variables)["boxed_type"] + ">"; + (*variables)["new_list"] = "newProtobufList"; + (*variables)["empty_list"] = "emptyProtobufList()"; + (*variables)["make_name_unmodifiable"] = + (*variables)["name"] + "_.makeImmutable()"; + (*variables)["repeated_index_get"] = + (*variables)["name"] + "_.get(index)"; + (*variables)["repeated_add"] = (*variables)["name"] + "_.add"; + (*variables)["repeated_set"] = (*variables)["name"] + "_.set"; + } + + 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 " : ""; + int fixed_size = FixedSize(GetType(descriptor)); + if (fixed_size != -1) { + (*variables)["fixed_size"] = SimpleItoa(fixed_size); + } + (*variables)["on_changed"] = + HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : ""; + + if (SupportFieldPresence(descriptor->file())) { + // 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"] = ""; + + if (descriptor->type() == FieldDescriptor::TYPE_BYTES) { + (*variables)["is_field_present_message"] = + "!" + (*variables)["name"] + "_.isEmpty()"; + } else { + (*variables)["is_field_present_message"] = + (*variables)["name"] + "_ != " + (*variables)["default"]; + } + } + + // For repeated builders, the underlying list tracks mutability state. + (*variables)["is_mutable"] = (*variables)["name"] + "_.isModifiable()"; + + (*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, + int builderBitIndex, + Context* context) + : descriptor_(descriptor), messageBitIndex_(messageBitIndex), + builderBitIndex_(builderBitIndex), context_(context), + name_resolver_(context->GetNameResolver()) { + SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex, + context->GetFieldGeneratorInfo(descriptor), + name_resolver_, &variables_); +} + +ImmutablePrimitiveFieldLiteGenerator::~ImmutablePrimitiveFieldLiteGenerator() {} + +int ImmutablePrimitiveFieldLiteGenerator::GetNumBitsForMessage() const { + return 1; +} + +int ImmutablePrimitiveFieldLiteGenerator::GetNumBitsForBuilder() const { + return 0; +} + +void ImmutablePrimitiveFieldLiteGenerator:: +GenerateInterfaceMembers(io::Printer* printer) const { + if (SupportFieldPresence(descriptor_->file())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$boolean has$capitalized_name$();\n"); + } + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$$type$ get$capitalized_name$();\n"); +} + +void ImmutablePrimitiveFieldLiteGenerator:: +GenerateMembers(io::Printer* printer) const { + printer->Print(variables_, + "private $field_type$ $name$_;\n"); + PrintExtraFieldInfo(variables_, printer); + if (SupportFieldPresence(descriptor_->file())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $get_has_field_bit_message$;\n" + "}\n"); + } + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$() {\n" + " return $name$_;\n" + "}\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void set$capitalized_name$($type$ value) {\n" + "$null_check$" + " $set_has_field_bit_message$\n" + " $name$_ = value;\n" + "}\n"); + + WriteFieldDocComment(printer, descriptor_); + 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 (SupportFieldPresence(descriptor_->file())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return instance.has$capitalized_name$();\n" + "}\n"); + } + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$() {\n" + " return instance.get$capitalized_name$();\n" + "}\n"); + + 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"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder clear$capitalized_name$() {\n" + " copyOnWrite();\n" + " instance.clear$capitalized_name$();\n" + " return this;\n" + "}\n"); +} + +void ImmutablePrimitiveFieldLiteGenerator:: +GenerateFieldBuilderInitializationCode(io::Printer* printer) const { + // noop for primitives +} + +void ImmutablePrimitiveFieldLiteGenerator:: +GenerateInitializationCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_ = $default$;\n"); +} + +void ImmutablePrimitiveFieldLiteGenerator:: +GenerateBuilderClearCode(io::Printer* printer) const { + // noop for primitives +} + +void ImmutablePrimitiveFieldLiteGenerator:: +GenerateMergingCode(io::Printer* printer) const { + if (SupportFieldPresence(descriptor_->file())) { + 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 ImmutablePrimitiveFieldLiteGenerator:: +GenerateBuildingCode(io::Printer* printer) const { + // noop for primitives +} + +void ImmutablePrimitiveFieldLiteGenerator:: +GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const { + // noop for scalars +} + +void ImmutablePrimitiveFieldLiteGenerator:: +GenerateParsingCode(io::Printer* printer) const { + printer->Print(variables_, + "$set_has_field_bit_message$\n" + "$name$_ = input.read$capitalized_type$();\n"); +} + +void ImmutablePrimitiveFieldLiteGenerator:: +GenerateParsingDoneCode(io::Printer* printer) const { + // noop for primitives. +} + +void ImmutablePrimitiveFieldLiteGenerator:: +GenerateSerializationCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($is_field_present_message$) {\n" + " output.write$capitalized_type$($number$, $name$_);\n" + "}\n"); +} + +void ImmutablePrimitiveFieldLiteGenerator:: +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 ImmutablePrimitiveFieldLiteGenerator:: +GenerateEqualsCode(io::Printer* printer) const { + switch (GetJavaType(descriptor_)) { + case JAVATYPE_INT: + case JAVATYPE_LONG: + case JAVATYPE_BOOLEAN: + printer->Print(variables_, + "result = result && (get$capitalized_name$()\n" + " == other.get$capitalized_name$());\n"); + break; + + case JAVATYPE_FLOAT: + printer->Print(variables_, + "result = result && (\n" + " java.lang.Float.floatToIntBits(get$capitalized_name$())\n" + " == java.lang.Float.floatToIntBits(\n" + " other.get$capitalized_name$()));\n"); + break; + + case JAVATYPE_DOUBLE: + printer->Print(variables_, + "result = result && (\n" + " java.lang.Double.doubleToLongBits(get$capitalized_name$())\n" + " == java.lang.Double.doubleToLongBits(\n" + " other.get$capitalized_name$()));\n"); + break; + + case JAVATYPE_STRING: + case JAVATYPE_BYTES: + printer->Print(variables_, + "result = result && get$capitalized_name$()\n" + " .equals(other.get$capitalized_name$());\n"); + break; + + case JAVATYPE_ENUM: + case JAVATYPE_MESSAGE: + default: + GOOGLE_LOG(FATAL) << "Can't get here."; + break; + } +} + +void ImmutablePrimitiveFieldLiteGenerator:: +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; + } +} + +string ImmutablePrimitiveFieldLiteGenerator::GetBoxedType() const { + return BoxedPrimitiveTypeName(GetJavaType(descriptor_)); +} + +// =================================================================== + +ImmutablePrimitiveOneofFieldLiteGenerator:: +ImmutablePrimitiveOneofFieldLiteGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex, + Context* context) + : ImmutablePrimitiveFieldLiteGenerator( + descriptor, messageBitIndex, builderBitIndex, 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); + if (SupportFieldPresence(descriptor_->file())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $has_oneof_case_message$;\n" + "}\n"); + } + + WriteFieldDocComment(printer, descriptor_); + 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"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void set$capitalized_name$($type$ value) {\n" + "$null_check$" + " $set_oneof_case_message$;\n" + " $oneof_name$_ = value;\n" + "}\n"); + + 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 ImmutablePrimitiveOneofFieldLiteGenerator:: +GenerateBuilderMembers(io::Printer* printer) const { + if (SupportFieldPresence(descriptor_->file())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return instance.has$capitalized_name$();\n" + "}\n"); + } + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$() {\n" + " return instance.get$capitalized_name$();\n" + "}\n"); + + 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"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder clear$capitalized_name$() {\n" + " copyOnWrite();\n" + " instance.clear$capitalized_name$();\n" + " return this;\n" + "}\n"); +} + +void ImmutablePrimitiveOneofFieldLiteGenerator:: +GenerateBuildingCode(io::Printer* printer) const { + // noop for primitives +} + +void ImmutablePrimitiveOneofFieldLiteGenerator:: +GenerateMergingCode(io::Printer* printer) const { + printer->Print(variables_, + "set$capitalized_name$(other.get$capitalized_name$());\n"); +} + +void ImmutablePrimitiveOneofFieldLiteGenerator:: +GenerateParsingCode(io::Printer* printer) const { + printer->Print(variables_, + "$set_oneof_case_message$;\n" + "$oneof_name$_ = input.read$capitalized_type$();\n"); +} + +void ImmutablePrimitiveOneofFieldLiteGenerator:: +GenerateSerializationCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($has_oneof_case_message$) {\n" + " output.write$capitalized_type$(\n" + " $number$, ($type$)(($boxed_type$) $oneof_name$_));\n" + "}\n"); +} + +void ImmutablePrimitiveOneofFieldLiteGenerator:: +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" + " $number$, ($type$)(($boxed_type$) $oneof_name$_));\n" + "}\n"); +} + +// =================================================================== + +RepeatedImmutablePrimitiveFieldLiteGenerator:: +RepeatedImmutablePrimitiveFieldLiteGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex, + Context* context) + : descriptor_(descriptor), messageBitIndex_(messageBitIndex), + builderBitIndex_(builderBitIndex), context_(context), + name_resolver_(context->GetNameResolver()) { + SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex, + context->GetFieldGeneratorInfo(descriptor), + name_resolver_, &variables_); +} + +RepeatedImmutablePrimitiveFieldLiteGenerator:: +~RepeatedImmutablePrimitiveFieldLiteGenerator() {} + +int RepeatedImmutablePrimitiveFieldLiteGenerator::GetNumBitsForMessage() const { + return 0; +} + +int RepeatedImmutablePrimitiveFieldLiteGenerator::GetNumBitsForBuilder() const { + return 0; +} + +void RepeatedImmutablePrimitiveFieldLiteGenerator:: +GenerateInterfaceMembers(io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$java.util.List<$boxed_type$> get$capitalized_name$List();\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$int get$capitalized_name$Count();\n"); + WriteFieldDocComment(printer, descriptor_); + 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); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public java.util.List<$boxed_type$>\n" + " get$capitalized_name$List() {\n" + " return $name$_;\n" // note: unmodifiable list + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public int get$capitalized_name$Count() {\n" + " return $name$_.size();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + " return $repeated_index_get$;\n" + "}\n"); + + if (descriptor_->options().packed() && + HasGeneratedMethods(descriptor_->containing_type())) { + printer->Print(variables_, + "private int $name$MemoizedSerializedSize = -1;\n"); + } + + printer->Print(variables_, + "private void ensure$capitalized_name$IsMutable() {\n" + " if (!$is_mutable$) {\n" + " $name$_ = $new_list$($name$_);\n" + " }\n" + "}\n"); + + WriteFieldDocComment(printer, descriptor_); + 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"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void add$capitalized_name$($type$ value) {\n" + "$null_check$" + " ensure$capitalized_name$IsMutable();\n" + " $repeated_add$(value);\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + 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"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void clear$capitalized_name$() {\n" + " $name$_ = $empty_list$;\n" + "}\n"); +} + +void RepeatedImmutablePrimitiveFieldLiteGenerator:: +GenerateBuilderMembers(io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$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"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public int get$capitalized_name$Count() {\n" + " return instance.get$capitalized_name$Count();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$ get$capitalized_name$(int index) {\n" + " return instance.get$capitalized_name$(index);\n" + "}\n"); + 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"); + 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"); + WriteFieldDocComment(printer, descriptor_); + 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"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder clear$capitalized_name$() {\n" + " copyOnWrite();\n" + " instance.clear$capitalized_name$();\n" + " return this;\n" + "}\n"); +} + +void RepeatedImmutablePrimitiveFieldLiteGenerator:: +GenerateFieldBuilderInitializationCode(io::Printer* printer) const { + // noop for primitives +} + +void RepeatedImmutablePrimitiveFieldLiteGenerator:: +GenerateInitializationCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_ = $empty_list$;\n"); +} + +void RepeatedImmutablePrimitiveFieldLiteGenerator:: +GenerateBuilderClearCode(io::Printer* printer) const { + // noop for primitives +} + +void RepeatedImmutablePrimitiveFieldLiteGenerator:: +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" + " } else {\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.addAll(other.$name$_);\n" + " }\n" + " $on_changed$\n" + "}\n"); +} + +void RepeatedImmutablePrimitiveFieldLiteGenerator:: +GenerateBuildingCode(io::Printer* printer) const { + // noop for primitives +} + +void RepeatedImmutablePrimitiveFieldLiteGenerator:: +GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const { + printer->Print(variables_, + "$name$_.makeImmutable();\n"); +} + +void RepeatedImmutablePrimitiveFieldLiteGenerator:: +GenerateParsingCode(io::Printer* printer) const { + printer->Print(variables_, + "if (!$is_mutable$) {\n" + " $name$_ = $new_list$();\n" + "}\n" + "$repeated_add$(input.read$capitalized_type$());\n"); +} + +void RepeatedImmutablePrimitiveFieldLiteGenerator:: +GenerateParsingCodeFromPacked(io::Printer* printer) const { + printer->Print(variables_, + "int length = input.readRawVarint32();\n" + "int limit = input.pushLimit(length);\n" + "if (!$is_mutable$ && input.getBytesUntilLimit() > 0) {\n" + " $name$_ = $new_list$();\n" + "}\n" + "while (input.getBytesUntilLimit() > 0) {\n" + " $repeated_add$(input.read$capitalized_type$());\n" + "}\n" + "input.popLimit(limit);\n"); +} + +void RepeatedImmutablePrimitiveFieldLiteGenerator:: +GenerateParsingDoneCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($is_mutable$) {\n" + " $make_name_unmodifiable$;\n" + "}\n"); +} + +void RepeatedImmutablePrimitiveFieldLiteGenerator:: +GenerateSerializationCode(io::Printer* printer) const { + if (descriptor_->options().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.writeRawVarint32($tag$);\n" + " output.writeRawVarint32($name$MemoizedSerializedSize);\n" + "}\n" + "for (int i = 0; i < $name$_.size(); i++) {\n" + " output.write$capitalized_type$NoTag($name$_.get(i));\n" + "}\n"); + } else { + printer->Print(variables_, + "for (int i = 0; i < $name$_.size(); i++) {\n" + " output.write$capitalized_type$($number$, $name$_.get(i));\n" + "}\n"); + } +} + +void RepeatedImmutablePrimitiveFieldLiteGenerator:: +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($name$_.get(i));\n" + "}\n"); + } else { + printer->Print(variables_, + "dataSize = $fixed_size$ * get$capitalized_name$List().size();\n"); + } + + printer->Print( + "size += dataSize;\n"); + + if (descriptor_->options().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_->options().packed()) { + printer->Print(variables_, + "$name$MemoizedSerializedSize = dataSize;\n"); + } + + printer->Outdent(); + printer->Print("}\n"); +} + +void RepeatedImmutablePrimitiveFieldLiteGenerator:: +GenerateEqualsCode(io::Printer* printer) const { + printer->Print(variables_, + "result = result && get$capitalized_name$List()\n" + " .equals(other.get$capitalized_name$List());\n"); +} + +void RepeatedImmutablePrimitiveFieldLiteGenerator:: +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"); +} + +string RepeatedImmutablePrimitiveFieldLiteGenerator::GetBoxedType() const { + return BoxedPrimitiveTypeName(GetJavaType(descriptor_)); +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/java/java_primitive_field_lite.h b/src/google/protobuf/compiler/java/java_primitive_field_lite.h new file mode 100644 index 00000000..ad603c2a --- /dev/null +++ b/src/google/protobuf/compiler/java/java_primitive_field_lite.h @@ -0,0 +1,163 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 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 <map> +#include <string> +#include <google/protobuf/compiler/java/java_field.h> + +namespace google { +namespace protobuf { + namespace compiler { + namespace java { + class Context; // context.h + class ClassNameResolver; // name_resolver.h + } + } +} + +namespace protobuf { +namespace compiler { +namespace java { + +class ImmutablePrimitiveFieldLiteGenerator + : public ImmutableFieldLiteGenerator { + public: + explicit ImmutablePrimitiveFieldLiteGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, + int builderBitIndex, Context* context); + ~ImmutablePrimitiveFieldLiteGenerator(); + + // implements ImmutableFieldLiteGenerator ------------------------------------ + int GetNumBitsForMessage() const; + int GetNumBitsForBuilder() const; + void GenerateInterfaceMembers(io::Printer* printer) const; + void GenerateMembers(io::Printer* printer) const; + void GenerateBuilderMembers(io::Printer* printer) const; + void GenerateInitializationCode(io::Printer* printer) const; + void GenerateBuilderClearCode(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateBuildingCode(io::Printer* printer) const; + void GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const; + void GenerateParsingCode(io::Printer* printer) const; + void GenerateParsingDoneCode(io::Printer* printer) const; + void GenerateSerializationCode(io::Printer* printer) const; + void GenerateSerializedSizeCode(io::Printer* printer) const; + void GenerateFieldBuilderInitializationCode(io::Printer* printer) const; + void GenerateEqualsCode(io::Printer* printer) const; + void GenerateHashCode(io::Printer* printer) const; + + string GetBoxedType() const; + + protected: + const FieldDescriptor* descriptor_; + map<string, string> variables_; + const int messageBitIndex_; + const int builderBitIndex_; + Context* context_; + ClassNameResolver* name_resolver_; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutablePrimitiveFieldLiteGenerator); +}; + +class ImmutablePrimitiveOneofFieldLiteGenerator + : public ImmutablePrimitiveFieldLiteGenerator { + public: + ImmutablePrimitiveOneofFieldLiteGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, + int builderBitIndex, Context* context); + ~ImmutablePrimitiveOneofFieldLiteGenerator(); + + void GenerateMembers(io::Printer* printer) const; + void GenerateBuilderMembers(io::Printer* printer) const; + void GenerateBuildingCode(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateParsingCode(io::Printer* printer) const; + void GenerateSerializationCode(io::Printer* printer) const; + void GenerateSerializedSizeCode(io::Printer* printer) const; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutablePrimitiveOneofFieldLiteGenerator); +}; + +class RepeatedImmutablePrimitiveFieldLiteGenerator + : public ImmutableFieldLiteGenerator { + public: + explicit RepeatedImmutablePrimitiveFieldLiteGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, + int builderBitIndex, Context* context); + virtual ~RepeatedImmutablePrimitiveFieldLiteGenerator(); + + // implements ImmutableFieldLiteGenerator ------------------------------------ + int GetNumBitsForMessage() const; + int GetNumBitsForBuilder() const; + void GenerateInterfaceMembers(io::Printer* printer) const; + void GenerateMembers(io::Printer* printer) const; + void GenerateBuilderMembers(io::Printer* printer) const; + void GenerateInitializationCode(io::Printer* printer) const; + void GenerateBuilderClearCode(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateBuildingCode(io::Printer* printer) const; + void GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const; + void GenerateParsingCode(io::Printer* printer) const; + void GenerateParsingCodeFromPacked(io::Printer* printer) const; + void GenerateParsingDoneCode(io::Printer* printer) const; + void GenerateSerializationCode(io::Printer* printer) const; + void GenerateSerializedSizeCode(io::Printer* printer) const; + void GenerateFieldBuilderInitializationCode(io::Printer* printer) const; + void GenerateEqualsCode(io::Printer* printer) const; + void GenerateHashCode(io::Printer* printer) const; + + string GetBoxedType() const; + + private: + const FieldDescriptor* descriptor_; + map<string, string> variables_; + const int messageBitIndex_; + const int builderBitIndex_; + 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/src/google/protobuf/compiler/java/java_string_field.cc b/src/google/protobuf/compiler/java/java_string_field.cc index 8aa5699c..68e863cc 100644 --- a/src/google/protobuf/compiler/java/java_string_field.cc +++ b/src/google/protobuf/compiler/java/java_string_field.cc @@ -208,7 +208,7 @@ GenerateInterfaceMembers(io::Printer* printer) const { void ImmutableStringFieldGenerator:: GenerateMembers(io::Printer* printer) const { printer->Print(variables_, - "private java.lang.Object $name$_;\n"); + "private volatile java.lang.Object $name$_;\n"); PrintExtraFieldInfo(variables_, printer); if (SupportFieldPresence(descriptor_->file())) { diff --git a/src/google/protobuf/compiler/java/java_string_field_lite.cc b/src/google/protobuf/compiler/java/java_string_field_lite.cc new file mode 100644 index 00000000..51bb245c --- /dev/null +++ b/src/google/protobuf/compiler/java/java_string_field_lite.cc @@ -0,0 +1,1013 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 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 <map> +#include <string> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/compiler/java/java_context.h> +#include <google/protobuf/compiler/java/java_doc_comment.h> +#include <google/protobuf/compiler/java/java_helpers.h> +#include <google/protobuf/compiler/java/java_name_resolver.h> +#include <google/protobuf/compiler/java/java_string_field_lite.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/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, + map<string, string>* variables) { + SetCommonFieldVariables(descriptor, info, variables); + + (*variables)["empty_list"] = "emptyLazyStringArrayList()"; + + (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver); + (*variables)["default_init"] = + "= " + ImmutableDefaultValue(descriptor, name_resolver); + (*variables)["capitalized_type"] = "String"; + (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor)); + (*variables)["tag_size"] = SimpleItoa( + WireFormat::TagSize(descriptor->number(), GetType(descriptor))); + (*variables)["null_check"] = + " if (value == null) {\n" + " throw new NullPointerException();\n" + " }\n"; + + // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported + // by the proto compiler + (*variables)["deprecation"] = descriptor->options().deprecated() + ? "@java.lang.Deprecated " : ""; + (*variables)["on_changed"] = + HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : ""; + + if (SupportFieldPresence(descriptor->file())) { + // 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"] = + "!get" + (*variables)["capitalized_name"] + "Bytes().isEmpty()"; + } + + // For repeated builders, the underlying list tracks mutability state. + (*variables)["is_mutable"] = (*variables)["name"] + "_.isModifiable()"; + + (*variables)["get_has_field_bit_from_local"] = + GenerateGetBitFromLocal(builderBitIndex); + (*variables)["set_has_field_bit_to_local"] = + GenerateSetBitToLocal(messageBitIndex); +} + +bool CheckUtf8(const FieldDescriptor* descriptor) { + return descriptor->file()->options().java_string_check_utf8(); +} + +} // namespace + +// =================================================================== + +ImmutableStringFieldLiteGenerator:: +ImmutableStringFieldLiteGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex, + Context* context) + : descriptor_(descriptor), messageBitIndex_(messageBitIndex), + builderBitIndex_(builderBitIndex), context_(context), + name_resolver_(context->GetNameResolver()) { + SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex, + context->GetFieldGeneratorInfo(descriptor), + name_resolver_, &variables_); +} + +ImmutableStringFieldLiteGenerator::~ImmutableStringFieldLiteGenerator() {} + +int ImmutableStringFieldLiteGenerator::GetNumBitsForMessage() const { + return 1; +} + +int ImmutableStringFieldLiteGenerator::GetNumBitsForBuilder() const { + return 0; +} + +// 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 vaid 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 ImmutableStringFieldLiteGenerator:: +GenerateInterfaceMembers(io::Printer* printer) const { + if (SupportFieldPresence(descriptor_->file())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$boolean has$capitalized_name$();\n"); + } + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$java.lang.String get$capitalized_name$();\n"); + WriteFieldDocComment(printer, descriptor_); + 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.Object $name$_;\n"); + PrintExtraFieldInfo(variables_, printer); + + if (SupportFieldPresence(descriptor_->file())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $get_has_field_bit_message$;\n" + "}\n"); + } + + WriteFieldDocComment(printer, descriptor_); + 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" + " 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"); + 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"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$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"); + + WriteFieldDocComment(printer, descriptor_); + 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"); + WriteFieldDocComment(printer, descriptor_); + 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"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void set$capitalized_name$Bytes(\n" + " com.google.protobuf.ByteString value) {\n" + "$null_check$"); + if (CheckUtf8(descriptor_)) { + printer->Print(variables_, + " checkByteStringIsUtf8(value);\n"); + } + printer->Print(variables_, + " $set_has_field_bit_message$\n" + " $name$_ = value;\n" + "}\n"); +} + +void ImmutableStringFieldLiteGenerator:: +GenerateBuilderMembers(io::Printer* printer) const { + if (SupportFieldPresence(descriptor_->file())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return instance.has$capitalized_name$();\n" + "}\n"); + } + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public java.lang.String get$capitalized_name$() {\n" + " return instance.get$capitalized_name$();\n" + "}\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public com.google.protobuf.ByteString\n" + " get$capitalized_name$Bytes() {\n" + " return instance.get$capitalized_name$Bytes();\n" + "}\n"); + + WriteFieldDocComment(printer, descriptor_); + 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"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder clear$capitalized_name$() {\n" + " copyOnWrite();\n" + " instance.clear$capitalized_name$();\n" + " return this;\n" + "}\n"); + + WriteFieldDocComment(printer, descriptor_); + 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"); +} + +void ImmutableStringFieldLiteGenerator:: +GenerateFieldBuilderInitializationCode(io::Printer* printer) const { + // noop for strings +} + +void ImmutableStringFieldLiteGenerator:: +GenerateInitializationCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_ = $default$;\n"); +} + +void ImmutableStringFieldLiteGenerator:: +GenerateMergingCode(io::Printer* printer) const { + if (SupportFieldPresence(descriptor_->file())) { + // 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_message$\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 ImmutableStringFieldLiteGenerator:: +GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const { + // noop for scalars +} + +void ImmutableStringFieldLiteGenerator:: +GenerateParsingCode(io::Printer* printer) const { + if (CheckUtf8(descriptor_)) { + printer->Print(variables_, + "String s = input.readStringRequireUtf8();\n" + "$set_has_field_bit_message$\n" + "$name$_ = s;\n"); + } else if (!HasDescriptorMethods(descriptor_->file())) { + // Lite runtime should attempt to reduce allocations by attempting to + // construct the string directly from the input stream buffer. This avoids + // spurious intermediary ByteString allocations, cutting overall allocations + // in half. + printer->Print(variables_, + "String s = input.readString();\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 ImmutableStringFieldLiteGenerator:: +GenerateParsingDoneCode(io::Printer* printer) const { + // noop for strings +} + +void ImmutableStringFieldLiteGenerator:: +GenerateSerializationCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($is_field_present_message$) {\n" + " output.writeBytes($number$, get$capitalized_name$Bytes());\n" + "}\n"); +} + +void ImmutableStringFieldLiteGenerator:: +GenerateSerializedSizeCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($is_field_present_message$) {\n" + " size += com.google.protobuf.CodedOutputStream\n" + " .computeBytesSize($number$, get$capitalized_name$Bytes());\n" + "}\n"); +} + +void ImmutableStringFieldLiteGenerator:: +GenerateEqualsCode(io::Printer* printer) const { + printer->Print(variables_, + "result = result && get$capitalized_name$()\n" + " .equals(other.get$capitalized_name$());\n"); +} + +void ImmutableStringFieldLiteGenerator:: +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"); +} + +string ImmutableStringFieldLiteGenerator::GetBoxedType() const { + return "java.lang.String"; +} + +// =================================================================== + +ImmutableStringOneofFieldLiteGenerator:: +ImmutableStringOneofFieldLiteGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex, + Context* context) + : ImmutableStringFieldLiteGenerator( + descriptor, messageBitIndex, builderBitIndex, 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); + + if (SupportFieldPresence(descriptor_->file())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return $has_oneof_case_message$;\n" + "}\n"); + } + + WriteFieldDocComment(printer, descriptor_); + 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"); + 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"); + WriteFieldDocComment(printer, descriptor_); + + 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"); + + WriteFieldDocComment(printer, descriptor_); + 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"); + 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"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void set$capitalized_name$Bytes(\n" + " com.google.protobuf.ByteString value) {\n" + "$null_check$"); + if (CheckUtf8(descriptor_)) { + printer->Print(variables_, + " checkByteStringIsUtf8(value);\n"); + } + printer->Print(variables_, + " $set_oneof_case_message$;\n" + " $oneof_name$_ = value;\n" + "}\n"); +} + +void ImmutableStringOneofFieldLiteGenerator:: +GenerateBuilderMembers(io::Printer* printer) const { + if (SupportFieldPresence(descriptor_->file())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public boolean has$capitalized_name$() {\n" + " return instance.has$capitalized_name$();\n" + "}\n"); + } + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public java.lang.String get$capitalized_name$() {\n" + " return instance.get$capitalized_name$();\n" + "}\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public com.google.protobuf.ByteString\n" + " get$capitalized_name$Bytes() {\n" + " return instance.get$capitalized_name$Bytes();\n" + "}\n"); + + WriteFieldDocComment(printer, descriptor_); + 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"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder clear$capitalized_name$() {\n" + " copyOnWrite();\n" + " instance.clear$capitalized_name$();\n" + " return this;\n" + "}\n"); + + WriteFieldDocComment(printer, descriptor_); + 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"); +} + +void ImmutableStringOneofFieldLiteGenerator:: +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 ImmutableStringOneofFieldLiteGenerator:: +GenerateParsingCode(io::Printer* printer) const { + if (CheckUtf8(descriptor_)) { + printer->Print(variables_, + "String s = input.readStringRequireUtf8();\n" + "$set_oneof_case_message$;\n" + "$oneof_name$_ = s;\n"); + } else if (!HasDescriptorMethods(descriptor_->file())) { + // Lite runtime should attempt to reduce allocations by attempting to + // construct the string directly from the input stream buffer. This avoids + // spurious intermediary ByteString allocations, cutting overall allocations + // in half. + printer->Print(variables_, + "String s = input.readString();\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 ImmutableStringOneofFieldLiteGenerator:: +GenerateSerializationCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($has_oneof_case_message$) {\n" + " output.writeBytes($number$, get$capitalized_name$Bytes());\n" + "}\n"); +} + +void ImmutableStringOneofFieldLiteGenerator:: +GenerateSerializedSizeCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($has_oneof_case_message$) {\n" + " size += com.google.protobuf.CodedOutputStream\n" + " .computeBytesSize($number$, get$capitalized_name$Bytes());\n" + "}\n"); +} + +// =================================================================== + +RepeatedImmutableStringFieldLiteGenerator:: +RepeatedImmutableStringFieldLiteGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex, + Context* context) + : descriptor_(descriptor), messageBitIndex_(messageBitIndex), + builderBitIndex_(builderBitIndex), context_(context), + name_resolver_(context->GetNameResolver()) { + SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex, + context->GetFieldGeneratorInfo(descriptor), + name_resolver_, &variables_); +} + +RepeatedImmutableStringFieldLiteGenerator:: +~RepeatedImmutableStringFieldLiteGenerator() {} + +int RepeatedImmutableStringFieldLiteGenerator::GetNumBitsForMessage() const { + return 0; +} + +int RepeatedImmutableStringFieldLiteGenerator::GetNumBitsForBuilder() const { + return 0; +} + +void RepeatedImmutableStringFieldLiteGenerator:: +GenerateInterfaceMembers(io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$com.google.protobuf.ProtocolStringList\n" + " get$capitalized_name$List();\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$int get$capitalized_name$Count();\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$java.lang.String get$capitalized_name$(int index);\n"); + WriteFieldDocComment(printer, descriptor_); + 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.LazyStringArrayList $name$_;\n"); + PrintExtraFieldInfo(variables_, printer); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public com.google.protobuf.ProtocolStringList\n" + " get$capitalized_name$List() {\n" + " return $name$_;\n" // note: unmodifiable list + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public int get$capitalized_name$Count() {\n" + " return $name$_.size();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public java.lang.String get$capitalized_name$(int index) {\n" + " return $name$_.get(index);\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public com.google.protobuf.ByteString\n" + " get$capitalized_name$Bytes(int index) {\n" + " return $name$_.getByteString(index);\n" + "}\n"); + + if (descriptor_->options().packed() && + HasGeneratedMethods(descriptor_->containing_type())) { + printer->Print(variables_, + "private int $name$MemoizedSerializedSize = -1;\n"); + } + + printer->Print(variables_, + "private void ensure$capitalized_name$IsMutable() {\n" + " if (!$is_mutable$) {\n" + " $name$_ = new com.google.protobuf.LazyStringArrayList($name$_);\n" + " }\n" + "}\n"); + + WriteFieldDocComment(printer, descriptor_); + 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"); + WriteFieldDocComment(printer, descriptor_); + 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"); + WriteFieldDocComment(printer, descriptor_); + 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"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void clear$capitalized_name$() {\n" + " $name$_ = $empty_list$;\n" + "}\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void add$capitalized_name$Bytes(\n" + " com.google.protobuf.ByteString value) {\n" + "$null_check$"); + if (CheckUtf8(descriptor_)) { + printer->Print(variables_, + " checkByteStringIsUtf8(value);\n"); + } + printer->Print(variables_, + " ensure$capitalized_name$IsMutable();\n" + " $name$_.add(value);\n" + "}\n"); +} + +void RepeatedImmutableStringFieldLiteGenerator:: +GenerateBuilderMembers(io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public com.google.protobuf.ProtocolStringList\n" + " get$capitalized_name$List() {\n" + " return ((com.google.protobuf.LazyStringList)\n" + " instance.get$capitalized_name$List()).getUnmodifiableView();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public int get$capitalized_name$Count() {\n" + " return instance.get$capitalized_name$Count();\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public java.lang.String get$capitalized_name$(int index) {\n" + " return instance.get$capitalized_name$(index);\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public com.google.protobuf.ByteString\n" + " get$capitalized_name$Bytes(int index) {\n" + " return instance.get$capitalized_name$Bytes(index);\n" + "}\n"); + WriteFieldDocComment(printer, descriptor_); + 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"); + WriteFieldDocComment(printer, descriptor_); + 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"); + WriteFieldDocComment(printer, descriptor_); + 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"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder clear$capitalized_name$() {\n" + " copyOnWrite();\n" + " instance.clear$capitalized_name$();\n" + " return this;\n" + "}\n"); + + WriteFieldDocComment(printer, descriptor_); + 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"); +} + +void RepeatedImmutableStringFieldLiteGenerator:: +GenerateFieldBuilderInitializationCode(io::Printer* printer) const { + // noop for strings +} + +void RepeatedImmutableStringFieldLiteGenerator:: +GenerateInitializationCode(io::Printer* printer) const { + printer->Print(variables_, "$name$_ = $empty_list$;\n"); +} + +void RepeatedImmutableStringFieldLiteGenerator:: +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" + " } else {\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.addAll(other.$name$_);\n" + " }\n" + " $on_changed$\n" + "}\n"); +} + +void RepeatedImmutableStringFieldLiteGenerator:: +GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const { + printer->Print(variables_, + "$name$_.makeImmutable();\n"); +} + +void RepeatedImmutableStringFieldLiteGenerator:: +GenerateParsingCode(io::Printer* printer) const { + if (CheckUtf8(descriptor_)) { + printer->Print(variables_, + "String s = input.readStringRequireUtf8();\n"); + } else if (!HasDescriptorMethods(descriptor_->file())) { + // Lite runtime should attempt to reduce allocations by attempting to + // construct the string directly from the input stream buffer. This avoids + // spurious intermediary ByteString allocations, cutting overall allocations + // in half. + printer->Print(variables_, + "String s = input.readString();\n"); + } else { + printer->Print(variables_, + "com.google.protobuf.ByteString bs = input.readBytes();\n"); + } + printer->Print(variables_, + "if (!$is_mutable$) {\n" + " $name$_ = new com.google.protobuf.LazyStringArrayList();\n" + "}\n"); + if (CheckUtf8(descriptor_) || !HasDescriptorMethods(descriptor_->file())) { + printer->Print(variables_, + "$name$_.add(s);\n"); + } else { + printer->Print(variables_, + "$name$_.add(bs);\n"); + } +} + +void RepeatedImmutableStringFieldLiteGenerator:: +GenerateParsingCodeFromPacked(io::Printer* printer) const { + printer->Print(variables_, + "int length = input.readRawVarint32();\n" + "int limit = input.pushLimit(length);\n" + "if (!$is_mutable$ && input.getBytesUntilLimit() > 0) {\n" + " $name$_ = new com.google.protobuf.LazyStringArrayList();\n" + "}\n" + "while (input.getBytesUntilLimit() > 0) {\n"); + if (CheckUtf8(descriptor_)) { + printer->Print(variables_, + " String s = input.readStringRequireUtf8();\n"); + } else { + printer->Print(variables_, + " String s = input.readString();\n"); + } + printer->Print(variables_, + " $name$.add(s);\n"); + printer->Print(variables_, + "}\n" + "input.popLimit(limit);\n"); +} + +void RepeatedImmutableStringFieldLiteGenerator:: +GenerateParsingDoneCode(io::Printer* printer) const { + printer->Print(variables_, + "if ($is_mutable$) {\n" + " $name$_.makeImmutable();\n" + "}\n"); +} + +void RepeatedImmutableStringFieldLiteGenerator:: +GenerateSerializationCode(io::Printer* printer) const { + if (descriptor_->options().packed()) { + printer->Print(variables_, + "if (get$capitalized_name$List().size() > 0) {\n" + " output.writeRawVarint32($tag$);\n" + " output.writeRawVarint32($name$MemoizedSerializedSize);\n" + "}\n" + "for (int i = 0; i < $name$_.size(); i++) {\n" + " output.write$capitalized_type$NoTag($name$_.get(i));\n" + "}\n"); + } else { + printer->Print(variables_, + "for (int i = 0; i < $name$_.size(); i++) {\n" + " output.writeBytes($number$, $name$_.getByteString(i));\n" + "}\n"); + } +} + +void RepeatedImmutableStringFieldLiteGenerator:: +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" + " .computeBytesSizeNoTag($name$_.getByteString(i));\n" + "}\n"); + + printer->Print( + "size += dataSize;\n"); + + if (descriptor_->options().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_->options().packed()) { + printer->Print(variables_, + "$name$MemoizedSerializedSize = dataSize;\n"); + } + + printer->Outdent(); + printer->Print("}\n"); +} + +void RepeatedImmutableStringFieldLiteGenerator:: +GenerateEqualsCode(io::Printer* printer) const { + printer->Print(variables_, + "result = result && get$capitalized_name$List()\n" + " .equals(other.get$capitalized_name$List());\n"); +} + +void RepeatedImmutableStringFieldLiteGenerator:: +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"); +} + +string RepeatedImmutableStringFieldLiteGenerator::GetBoxedType() const { + return "String"; +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/java/java_string_field_lite.h b/src/google/protobuf/compiler/java/java_string_field_lite.h new file mode 100644 index 00000000..9d93b307 --- /dev/null +++ b/src/google/protobuf/compiler/java/java_string_field_lite.h @@ -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. + +// 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 <map> +#include <string> +#include <google/protobuf/compiler/java/java_field.h> + +namespace google { +namespace protobuf { + namespace compiler { + namespace java { + class Context; // context.h + class ClassNameResolver; // name_resolver.h + } + } +} + +namespace protobuf { +namespace compiler { +namespace java { + +class ImmutableStringFieldLiteGenerator : public ImmutableFieldLiteGenerator { + public: + explicit ImmutableStringFieldLiteGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, + int builderBitIndex, Context* context); + ~ImmutableStringFieldLiteGenerator(); + + // implements ImmutableFieldLiteGenerator ------------------------------------ + int GetNumBitsForMessage() const; + int GetNumBitsForBuilder() const; + void GenerateInterfaceMembers(io::Printer* printer) const; + void GenerateMembers(io::Printer* printer) const; + void GenerateBuilderMembers(io::Printer* printer) const; + void GenerateInitializationCode(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const; + void GenerateParsingCode(io::Printer* printer) const; + void GenerateParsingDoneCode(io::Printer* printer) const; + void GenerateSerializationCode(io::Printer* printer) const; + void GenerateSerializedSizeCode(io::Printer* printer) const; + void GenerateFieldBuilderInitializationCode(io::Printer* printer) const; + void GenerateEqualsCode(io::Printer* printer) const; + void GenerateHashCode(io::Printer* printer) const; + + string GetBoxedType() const; + + protected: + const FieldDescriptor* descriptor_; + map<string, string> variables_; + const int messageBitIndex_; + const int builderBitIndex_; + Context* context_; + ClassNameResolver* name_resolver_; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableStringFieldLiteGenerator); +}; + +class ImmutableStringOneofFieldLiteGenerator + : public ImmutableStringFieldLiteGenerator { + public: + ImmutableStringOneofFieldLiteGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, + int builderBitIndex, Context* context); + ~ImmutableStringOneofFieldLiteGenerator(); + + private: + void GenerateMembers(io::Printer* printer) const; + void GenerateBuilderMembers(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateParsingCode(io::Printer* printer) const; + void GenerateSerializationCode(io::Printer* printer) const; + void GenerateSerializedSizeCode(io::Printer* printer) const; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableStringOneofFieldLiteGenerator); +}; + +class RepeatedImmutableStringFieldLiteGenerator + : public ImmutableFieldLiteGenerator { + public: + explicit RepeatedImmutableStringFieldLiteGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, + int builderBitIndex, Context* context); + ~RepeatedImmutableStringFieldLiteGenerator(); + + // implements ImmutableFieldLiteGenerator ------------------------------------ + int GetNumBitsForMessage() const; + int GetNumBitsForBuilder() const; + void GenerateInterfaceMembers(io::Printer* printer) const; + void GenerateMembers(io::Printer* printer) const; + void GenerateBuilderMembers(io::Printer* printer) const; + void GenerateInitializationCode(io::Printer* printer) const; + void GenerateMergingCode(io::Printer* printer) const; + void GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const; + void GenerateParsingCode(io::Printer* printer) const; + void GenerateParsingCodeFromPacked(io::Printer* printer) const; + void GenerateParsingDoneCode(io::Printer* printer) const; + void GenerateSerializationCode(io::Printer* printer) const; + void GenerateSerializedSizeCode(io::Printer* printer) const; + void GenerateFieldBuilderInitializationCode(io::Printer* printer) const; + void GenerateEqualsCode(io::Printer* printer) const; + void GenerateHashCode(io::Printer* printer) const; + + string GetBoxedType() const; + + private: + const FieldDescriptor* descriptor_; + map<string, string> variables_; + const int messageBitIndex_; + const int builderBitIndex_; + Context* context_; + 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/src/google/protobuf/compiler/javanano/javanano_enum.cc b/src/google/protobuf/compiler/javanano/javanano_enum.cc index f934b05f..c6e8dfe9 100644 --- a/src/google/protobuf/compiler/javanano/javanano_enum.cc +++ b/src/google/protobuf/compiler/javanano/javanano_enum.cc @@ -73,13 +73,45 @@ void EnumGenerator::Generate(io::Printer* printer) { "// enum $classname$\n", "classname", descriptor_->name()); + const string classname = RenameJavaKeywords(descriptor_->name()); + // Start of container interface + // If generating intdefs, we use the container interface as the intdef if + // present. Otherwise, we just make an empty @interface parallel to the + // constants. + bool use_intdef = params_.generate_intdefs(); bool use_shell_class = params_.java_enum_style(); - if (use_shell_class) { - printer->Print( - "public interface $classname$ {\n", - "classname", RenameJavaKeywords(descriptor_->name())); + if (use_intdef) { + // @IntDef annotation so tools can enforce correctness + // Annotations will be discarded by the compiler + printer->Print("@java.lang.annotation.Retention(" + "java.lang.annotation.RetentionPolicy.SOURCE)\n" + "@android.support.annotation.IntDef({\n"); printer->Indent(); + for (int i = 0; i < canonical_values_.size(); i++) { + const string constant_name = + RenameJavaKeywords(canonical_values_[i]->name()); + if (use_shell_class) { + printer->Print("$classname$.$name$,\n", + "classname", classname, + "name", constant_name); + } else { + printer->Print("$name$,\n", "name", constant_name); + } + } + printer->Outdent(); + printer->Print("})\n"); + } + if (use_shell_class || use_intdef) { + printer->Print( + "public $at_for_intdef$interface $classname$ {\n", + "classname", classname, + "at_for_intdef", use_intdef ? "@" : ""); + if (use_shell_class) { + printer->Indent(); + } else { + printer->Print("}\n\n"); + } } // Canonical values diff --git a/src/google/protobuf/compiler/javanano/javanano_enum_field.cc b/src/google/protobuf/compiler/javanano/javanano_enum_field.cc index 8a59d323..7666db38 100644 --- a/src/google/protobuf/compiler/javanano/javanano_enum_field.cc +++ b/src/google/protobuf/compiler/javanano/javanano_enum_field.cc @@ -76,6 +76,10 @@ void SetEnumVariables(const Params& params, internal::WireFormatLite::MakeTag(descriptor->number(), internal::WireFormat::WireTypeForFieldType(descriptor->type()))); (*variables)["message_name"] = descriptor->containing_type()->name(); + const EnumDescriptor* enum_type = descriptor->enum_type(); + (*variables)["message_type_intdef"] = "@" + + ToJavaName(params, enum_type->name(), true, + enum_type->containing_type(), enum_type->file()); } void LoadEnumValues(const Params& params, @@ -116,8 +120,10 @@ EnumFieldGenerator::~EnumFieldGenerator() {} void EnumFieldGenerator:: GenerateMembers(io::Printer* printer, bool /* unused lazy_init */) const { - printer->Print(variables_, - "public $type$ $name$;\n"); + if (params_.generate_intdefs()) { + printer->Print(variables_, "$message_type_intdef$\n"); + } + printer->Print(variables_, "public $type$ $name$;\n"); if (params_.generate_has()) { printer->Print(variables_, @@ -256,12 +262,22 @@ AccessorEnumFieldGenerator::~AccessorEnumFieldGenerator() {} void AccessorEnumFieldGenerator:: GenerateMembers(io::Printer* printer, bool /* unused lazy_init */) const { + printer->Print(variables_, "private int $name$_;\n"); + if (params_.generate_intdefs()) { + printer->Print(variables_, "$message_type_intdef$\n"); + } printer->Print(variables_, - "private int $name$_;\n" "public int get$capitalized_name$() {\n" " return $name$_;\n" "}\n" - "public $message_name$ set$capitalized_name$(int value) {\n" + "public $message_name$ set$capitalized_name$("); + if (params_.generate_intdefs()) { + printer->Print(variables_, + "\n" + " $message_type_intdef$ "); + } + printer->Print(variables_, + "int value) {\n" " $name$_ = value;\n" " $set_has$;\n" " return this;\n" @@ -499,6 +515,14 @@ GenerateSerializedSizeCode(io::Printer* printer) const { } void RepeatedEnumFieldGenerator:: +GenerateFixClonedCode(io::Printer* printer) const { + printer->Print(variables_, + "if (this.$name$ != null && this.$name$.length > 0) {\n" + " cloned.$name$ = this.$name$.clone();\n" + "}\n"); +} + +void RepeatedEnumFieldGenerator:: GenerateEqualsCode(io::Printer* printer) const { printer->Print(variables_, "if (!com.google.protobuf.nano.InternalNano.equals(\n" diff --git a/src/google/protobuf/compiler/javanano/javanano_enum_field.h b/src/google/protobuf/compiler/javanano/javanano_enum_field.h index 00adc61f..b94790d6 100644 --- a/src/google/protobuf/compiler/javanano/javanano_enum_field.h +++ b/src/google/protobuf/compiler/javanano/javanano_enum_field.h @@ -106,6 +106,7 @@ class RepeatedEnumFieldGenerator : public FieldGenerator { void GenerateSerializedSizeCode(io::Printer* printer) const; void GenerateEqualsCode(io::Printer* printer) const; void GenerateHashCodeCode(io::Printer* printer) const; + void GenerateFixClonedCode(io::Printer* printer) const; private: void GenerateRepeatedDataSizeCode(io::Printer* printer) const; diff --git a/src/google/protobuf/compiler/javanano/javanano_extension.cc b/src/google/protobuf/compiler/javanano/javanano_extension.cc index 754ed550..0b9d1d8d 100644 --- a/src/google/protobuf/compiler/javanano/javanano_extension.cc +++ b/src/google/protobuf/compiler/javanano/javanano_extension.cc @@ -140,7 +140,7 @@ void ExtensionGenerator::Generate(io::Printer* printer) const { " com.google.protobuf.nano.Extension.create$repeated$$ext_type$(\n" " com.google.protobuf.nano.Extension.$type$,\n" " $class$.class,\n" - " $tag_params$);\n"); + " $tag_params$L);\n"); } } // namespace javanano diff --git a/src/google/protobuf/compiler/javanano/javanano_field.h b/src/google/protobuf/compiler/javanano/javanano_field.h index c2cf091c..57c221f4 100644 --- a/src/google/protobuf/compiler/javanano/javanano_field.h +++ b/src/google/protobuf/compiler/javanano/javanano_field.h @@ -83,6 +83,7 @@ class FieldGenerator { virtual void GenerateSerializedSizeCode(io::Printer* printer) const = 0; virtual void GenerateEqualsCode(io::Printer* printer) const = 0; virtual void GenerateHashCodeCode(io::Printer* printer) const = 0; + virtual void GenerateFixClonedCode(io::Printer* printer) const {} protected: const Params& params_; diff --git a/src/google/protobuf/compiler/javanano/javanano_generator.cc b/src/google/protobuf/compiler/javanano/javanano_generator.cc index b5fbcd5f..ad215cb7 100644 --- a/src/google/protobuf/compiler/javanano/javanano_generator.cc +++ b/src/google/protobuf/compiler/javanano/javanano_generator.cc @@ -152,6 +152,12 @@ bool JavaNanoGenerator::Generate(const FileDescriptor* file, params.set_ignore_services(option_value == "true"); } else if (option_name == "parcelable_messages") { params.set_parcelable_messages(option_value == "true"); + } else if (option_name == "generate_clone") { + params.set_generate_clone(option_value == "true"); + } else if (option_name == "generate_intdefs") { + params.set_generate_intdefs(option_value == "true"); + } else if (option_name == "generate_clear") { + params.set_generate_clear(option_value == "true"); } else { *error = "Ignore unknown javanano generator option: " + option_name; } diff --git a/src/google/protobuf/compiler/javanano/javanano_message.cc b/src/google/protobuf/compiler/javanano/javanano_message.cc index 707f6b84..a41da5ae 100644 --- a/src/google/protobuf/compiler/javanano/javanano_message.cc +++ b/src/google/protobuf/compiler/javanano/javanano_message.cc @@ -136,21 +136,37 @@ void MessageGenerator::Generate(io::Printer* printer) { } if (params_.store_unknown_fields() && params_.parcelable_messages()) { printer->Print( - " com.google.protobuf.nano.android.ParcelableExtendableMessageNano<$classname$> {\n", + " com.google.protobuf.nano.android.ParcelableExtendableMessageNano<$classname$>", "classname", descriptor_->name()); } else if (params_.store_unknown_fields()) { printer->Print( - " com.google.protobuf.nano.ExtendableMessageNano<$classname$> {\n", + " com.google.protobuf.nano.ExtendableMessageNano<$classname$>", "classname", descriptor_->name()); } else if (params_.parcelable_messages()) { printer->Print( - " com.google.protobuf.nano.android.ParcelableMessageNano {\n"); + " com.google.protobuf.nano.android.ParcelableMessageNano"); } else { printer->Print( - " com.google.protobuf.nano.MessageNano {\n"); + " com.google.protobuf.nano.MessageNano"); + } + if (params_.generate_clone()) { + printer->Print(" implements java.lang.Cloneable {\n"); + } else { + printer->Print(" {\n"); } printer->Indent(); + if (params_.parcelable_messages()) { + printer->Print( + "\n" + "// Used by Parcelable\n" + "@SuppressWarnings({\"unused\"})\n" + "public static final android.os.Parcelable.Creator<$classname$> CREATOR =\n" + " new com.google.protobuf.nano.android.ParcelableMessageNanoCreator<\n" + " $classname$>($classname$.class);\n", + "classname", descriptor_->name()); + } + // Nested types and extensions for (int i = 0; i < descriptor_->extension_count(); i++) { ExtensionGenerator(descriptor_->extension(i), params_).Generate(printer); @@ -288,20 +304,28 @@ void MessageGenerator::Generate(io::Printer* printer) { } printer->Print("}\n"); } else { + printer->Print( + "\n" + "public $classname$() {\n", + "classname", descriptor_->name()); if (params_.generate_clear()) { - printer->Print( - "\n" - "public $classname$() {\n" - " clear();\n" - "}\n", - "classname", descriptor_->name()); + printer->Print(" clear();\n"); + } else { + printer->Indent(); + GenerateFieldInitializers(printer); + printer->Outdent(); } + printer->Print("}\n"); } // Other methods in this class GenerateClear(printer); + if (params_.generate_clone()) { + GenerateClone(printer); + } + if (params_.generate_equals()) { GenerateEquals(printer); GenerateHashCode(printer); @@ -495,6 +519,15 @@ void MessageGenerator::GenerateClear(io::Printer* printer) { "classname", descriptor_->name()); printer->Indent(); + GenerateFieldInitializers(printer); + + printer->Outdent(); + printer->Print( + " return this;\n" + "}\n"); +} + +void MessageGenerator::GenerateFieldInitializers(io::Printer* printer) { // Clear bit fields. int totalInts = (field_generators_.total_bits() + 31) / 32; for (int i = 0; i < totalInts; i++) { @@ -520,12 +553,34 @@ void MessageGenerator::GenerateClear(io::Printer* printer) { if (params_.store_unknown_fields()) { printer->Print("unknownFieldData = null;\n"); } + printer->Print("cachedSize = -1;\n"); +} + +void MessageGenerator::GenerateClone(io::Printer* printer) { + printer->Print( + "@Override\n" + "public $classname$ clone() {\n", + "classname", descriptor_->name()); + printer->Indent(); + + printer->Print( + "$classname$ cloned;\n" + "try {\n" + " cloned = ($classname$) super.clone();\n" + "} catch (java.lang.CloneNotSupportedException e) {\n" + " throw new java.lang.AssertionError(e);\n" + "}\n", + "classname", descriptor_->name()); + + for (int i = 0; i < descriptor_->field_count(); i++) { + field_generators_.get(descriptor_->field(i)).GenerateFixClonedCode(printer); + } printer->Outdent(); printer->Print( - " cachedSize = -1;\n" - " return this;\n" - "}\n"); + " return cloned;\n" + "}\n" + "\n"); } void MessageGenerator::GenerateEquals(io::Printer* printer) { @@ -568,7 +623,11 @@ void MessageGenerator::GenerateEquals(io::Printer* printer) { if (params_.store_unknown_fields()) { printer->Print( - "return unknownFieldDataEquals(other);\n"); + "if (unknownFieldData == null || unknownFieldData.isEmpty()) {\n" + " return other.unknownFieldData == null || other.unknownFieldData.isEmpty();\n" + "} else {\n" + " return unknownFieldData.equals(other.unknownFieldData);\n" + "}"); } else { printer->Print( "return true;\n"); @@ -598,7 +657,9 @@ void MessageGenerator::GenerateHashCode(io::Printer* printer) { if (params_.store_unknown_fields()) { printer->Print( - "result = 31 * result + unknownFieldDataHashCode();\n"); + "result = 31 * result + \n" + " (unknownFieldData == null || unknownFieldData.isEmpty() ? 0 : \n" + " unknownFieldData.hashCode());\n"); } printer->Print("return result;\n"); diff --git a/src/google/protobuf/compiler/javanano/javanano_message.h b/src/google/protobuf/compiler/javanano/javanano_message.h index 6f25a3a0..281ec64f 100644 --- a/src/google/protobuf/compiler/javanano/javanano_message.h +++ b/src/google/protobuf/compiler/javanano/javanano_message.h @@ -77,8 +77,10 @@ class MessageGenerator { const FieldDescriptor* field); void GenerateClear(io::Printer* printer); + void GenerateFieldInitializers(io::Printer* printer); void GenerateEquals(io::Printer* printer); void GenerateHashCode(io::Printer* printer); + void GenerateClone(io::Printer* printer); const Params& params_; const Descriptor* descriptor_; diff --git a/src/google/protobuf/compiler/javanano/javanano_message_field.cc b/src/google/protobuf/compiler/javanano/javanano_message_field.cc index 181c4060..d1d04b52 100644 --- a/src/google/protobuf/compiler/javanano/javanano_message_field.cc +++ b/src/google/protobuf/compiler/javanano/javanano_message_field.cc @@ -127,6 +127,14 @@ GenerateSerializedSizeCode(io::Printer* printer) const { } void MessageFieldGenerator:: +GenerateFixClonedCode(io::Printer* printer) const { + printer->Print(variables_, + "if (this.$name$ != null) {\n" + " cloned.$name$ = this.$name$.clone();\n" + "}\n"); +} + +void MessageFieldGenerator:: GenerateEqualsCode(io::Printer* printer) const { printer->Print(variables_, "if (this.$name$ == null) { \n" @@ -213,6 +221,14 @@ GenerateSerializedSizeCode(io::Printer* printer) const { } void MessageOneofFieldGenerator:: +GenerateFixClonedCode(io::Printer* printer) const { + printer->Print(variables_, + "if (this.$oneof_name$ != null) {\n" + " cloned.$oneof_name$ = this.$oneof_name$.clone();\n" + "}\n"); +} + +void MessageOneofFieldGenerator:: GenerateEqualsCode(io::Printer* printer) const { GenerateOneofFieldEquals(descriptor_, variables_, printer); } @@ -313,6 +329,19 @@ GenerateSerializedSizeCode(io::Printer* printer) const { } void RepeatedMessageFieldGenerator:: +GenerateFixClonedCode(io::Printer* printer) const { + printer->Print(variables_, + "if (this.$name$ != null && this.$name$.length > 0) {\n" + " cloned.$name$ = new $type$[this.$name$.length];\n" + " for (int i = 0; i < this.$name$.length; i++) {\n" + " if (this.$name$[i] != null) {\n" + " cloned.$name$[i] = this.$name$[i].clone();\n" + " }\n" + " }\n" + "}\n"); +} + +void RepeatedMessageFieldGenerator:: GenerateEqualsCode(io::Printer* printer) const { printer->Print(variables_, "if (!com.google.protobuf.nano.InternalNano.equals(\n" diff --git a/src/google/protobuf/compiler/javanano/javanano_message_field.h b/src/google/protobuf/compiler/javanano/javanano_message_field.h index 6c615f5e..e074735c 100644 --- a/src/google/protobuf/compiler/javanano/javanano_message_field.h +++ b/src/google/protobuf/compiler/javanano/javanano_message_field.h @@ -58,6 +58,7 @@ class MessageFieldGenerator : public FieldGenerator { void GenerateSerializedSizeCode(io::Printer* printer) const; void GenerateEqualsCode(io::Printer* printer) const; void GenerateHashCodeCode(io::Printer* printer) const; + void GenerateFixClonedCode(io::Printer* printer) const; private: const FieldDescriptor* descriptor_; @@ -80,6 +81,7 @@ class MessageOneofFieldGenerator : public FieldGenerator { void GenerateSerializedSizeCode(io::Printer* printer) const; void GenerateEqualsCode(io::Printer* printer) const; void GenerateHashCodeCode(io::Printer* printer) const; + void GenerateFixClonedCode(io::Printer* printer) const; private: const FieldDescriptor* descriptor_; @@ -102,6 +104,7 @@ class RepeatedMessageFieldGenerator : public FieldGenerator { void GenerateSerializedSizeCode(io::Printer* printer) const; void GenerateEqualsCode(io::Printer* printer) const; void GenerateHashCodeCode(io::Printer* printer) const; + void GenerateFixClonedCode(io::Printer* printer) const; private: const FieldDescriptor* descriptor_; diff --git a/src/google/protobuf/compiler/javanano/javanano_params.h b/src/google/protobuf/compiler/javanano/javanano_params.h index 4691f360..e3b4bb93 100644 --- a/src/google/protobuf/compiler/javanano/javanano_params.h +++ b/src/google/protobuf/compiler/javanano/javanano_params.h @@ -66,6 +66,8 @@ class Params { bool parcelable_messages_; bool reftypes_primitive_enums_; bool generate_clear_; + bool generate_clone_; + bool generate_intdefs_; public: Params(const string & base_name) : @@ -81,7 +83,9 @@ class Params { ignore_services_(false), parcelable_messages_(false), reftypes_primitive_enums_(false), - generate_clear_(true) { + generate_clear_(true), + generate_clone_(false), + generate_intdefs_(false) { } const string& base_name() const { @@ -231,6 +235,20 @@ class Params { bool generate_clear() const { return generate_clear_; } + + void set_generate_clone(bool value) { + generate_clone_ = value; + } + bool generate_clone() const { + return generate_clone_; + } + + void set_generate_intdefs(bool value) { + generate_intdefs_ = value; + } + bool generate_intdefs() const { + return generate_intdefs_; + } }; } // namespace javanano diff --git a/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc b/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc index 41bad0a6..978abf2c 100644 --- a/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc +++ b/src/google/protobuf/compiler/javanano/javanano_primitive_field.cc @@ -364,6 +364,14 @@ GenerateSerializedSizeCode(io::Printer* printer) const { } } +void RepeatedPrimitiveFieldGenerator:: +GenerateFixClonedCode(io::Printer* printer) const { + printer->Print(variables_, + "if (this.$name$ != null && this.$name$.length > 0) {\n" + " cloned.$name$ = this.$name$.clone();\n" + "}\n"); +} + void PrimitiveFieldGenerator:: GenerateEqualsCode(io::Printer* printer) const { // We define equality as serialized form equality. If generate_has(), diff --git a/src/google/protobuf/compiler/javanano/javanano_primitive_field.h b/src/google/protobuf/compiler/javanano/javanano_primitive_field.h index ca7116ff..a01981dd 100644 --- a/src/google/protobuf/compiler/javanano/javanano_primitive_field.h +++ b/src/google/protobuf/compiler/javanano/javanano_primitive_field.h @@ -131,6 +131,7 @@ class RepeatedPrimitiveFieldGenerator : public FieldGenerator { void GenerateSerializedSizeCode(io::Printer* printer) const; void GenerateEqualsCode(io::Printer* printer) const; void GenerateHashCodeCode(io::Printer* printer) const; + void GenerateFixClonedCode(io::Printer* printer) const; private: void GenerateRepeatedDataSizeCode(io::Printer* printer) const; diff --git a/src/google/protobuf/compiler/main.cc b/src/google/protobuf/compiler/main.cc index 931b8fa3..4815a726 100644 --- a/src/google/protobuf/compiler/main.cc +++ b/src/google/protobuf/compiler/main.cc @@ -36,6 +36,8 @@ #include <google/protobuf/compiler/java/java_generator.h> #include <google/protobuf/compiler/javanano/javanano_generator.h> #include <google/protobuf/compiler/ruby/ruby_generator.h> +#include <google/protobuf/compiler/csharp/csharp_generator.h> +#include <google/protobuf/compiler/objectivec/objectivec_generator.h> int main(int argc, char* argv[]) { @@ -68,5 +70,15 @@ int main(int argc, char* argv[]) { cli.RegisterGenerator("--ruby_out", &rb_generator, "Generate Ruby source file."); + // CSharp + google::protobuf::compiler::csharp::Generator csharp_generator; + cli.RegisterGenerator("--csharp_out", &csharp_generator, + "Generate C# source file."); + + // Objective C + google::protobuf::compiler::objectivec::ObjectiveCGenerator objc_generator; + cli.RegisterGenerator("--objc_out", &objc_generator, + "Generate Objective C header and source."); + return cli.Run(argc, argv); } diff --git a/src/google/protobuf/compiler/objectivec/objectivec_enum.cc b/src/google/protobuf/compiler/objectivec/objectivec_enum.cc new file mode 100644 index 00000000..b7c720d2 --- /dev/null +++ b/src/google/protobuf/compiler/objectivec/objectivec_enum.cc @@ -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. + +#include <map> +#include <string> + +#include <google/protobuf/compiler/objectivec/objectivec_enum.h> +#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor) + : descriptor_(descriptor), + name_(EnumName(descriptor_)) { + 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); + } + all_values_.push_back(value); + } +} + +EnumGenerator::~EnumGenerator() {} + +void EnumGenerator::GenerateHeader(io::Printer* printer) { + string enum_comments; + SourceLocation location; + if (descriptor_->GetSourceLocation(&location)) { + enum_comments = BuildCommentsString(location); + } else { + enum_comments = ""; + } + + printer->Print( + "#pragma mark - Enum $name$\n" + "\n", + "name", name_); + + printer->Print("$comments$typedef GPB_ENUM($name$) {\n", + "comments", enum_comments, + "name", name_); + printer->Indent(); + + if (HasPreservingUnknownEnumSemantics(descriptor_->file())) { + // Include the unknown value. + printer->Print( + "$name$_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue,\n", + "name", name_); + } + + for (int i = 0; i < all_values_.size(); i++) { + SourceLocation location; + if (all_values_[i]->GetSourceLocation(&location)) { + string comments = BuildCommentsString(location).c_str(); + if (comments.length() > 0) { + if (i > 0) { + printer->Print("\n"); + } + printer->Print(comments.c_str()); + } + } + + printer->Print( + "$name$ = $value$,\n", + "name", EnumValueName(all_values_[i]), + "value", SimpleItoa(all_values_[i]->number())); + } + printer->Outdent(); + printer->Print( + "};\n" + "\n" + "GPBEnumDescriptor *$name$_EnumDescriptor(void);\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_); + + printer->Print( + "GPBEnumDescriptor *$name$_EnumDescriptor(void) {\n" + " static GPBEnumDescriptor *descriptor = NULL;\n" + " if (!descriptor) {\n" + " static GPBMessageEnumValueDescription values[] = {\n", + "name", name_); + printer->Indent(); + printer->Indent(); + printer->Indent(); + + // 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; + + for (int i = 0; i < all_values_.size(); i++) { + ++enum_value_description_key; + string short_name(EnumValueShortName(all_values_[i])); + printer->Print("{ .name = \"$short_name$\", .number = $name$ },\n", + "short_name", short_name, + "name", EnumValueName(all_values_[i])); + if (UnCamelCaseEnumShortName(short_name) != all_values_[i]->name()) { + text_format_decode_data.AddString(enum_value_description_key, short_name, + all_values_[i]->name()); + } + } + printer->Outdent(); + printer->Outdent(); + printer->Outdent(); + printer->Print(" };\n"); + if (text_format_decode_data.num_entries() == 0) { + printer->Print( + " descriptor = [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol($name$)\n" + " values:values\n" + " valueCount:sizeof(values) / sizeof(GPBMessageEnumValueDescription)\n" + " enumVerifier:$name$_IsValidValue];\n", + "name", name_); + } else { + printer->Print( + " static const char *extraTextFormatInfo = \"$extraTextFormatInfo$\";\n" + " descriptor = [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol($name$)\n" + " values:values\n" + " valueCount:sizeof(values) / sizeof(GPBMessageEnumValueDescription)\n" + " enumVerifier:$name$_IsValidValue\n" + " extraTextFormatInfo:extraTextFormatInfo];\n", + "name", name_, + "extraTextFormatInfo", CEscape(text_format_decode_data.Data())); + } + printer->Print( + " }\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/src/google/protobuf/compiler/objectivec/objectivec_enum.h b/src/google/protobuf/compiler/objectivec/objectivec_enum.h new file mode 100644 index 00000000..0b41cf73 --- /dev/null +++ b/src/google/protobuf/compiler/objectivec/objectivec_enum.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_OBJECTIVEC_ENUM_H__ +#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_H__ + +#include <string> +#include <set> +#include <vector> +#include <google/protobuf/descriptor.h> + +namespace google { +namespace protobuf { +namespace io { +class Printer; // printer.h +} +} + +namespace protobuf { +namespace compiler { +namespace objectivec { + +class EnumGenerator { + public: + explicit EnumGenerator(const EnumDescriptor* descriptor); + ~EnumGenerator(); + + void GenerateHeader(io::Printer* printer); + void GenerateSource(io::Printer* printer); + + const string& name() const { return name_; } + + private: + const EnumDescriptor* descriptor_; + vector<const EnumValueDescriptor*> base_values_; + vector<const EnumValueDescriptor*> all_values_; + const string name_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator); +}; + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_H__ diff --git a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc new file mode 100644 index 00000000..d6609692 --- /dev/null +++ b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc @@ -0,0 +1,150 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (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 <google/protobuf/compiler/objectivec/objectivec_enum_field.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +namespace { +void SetEnumVariables(const FieldDescriptor* descriptor, + map<string, string>* variables) { + 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; + } + // TODO(thomasvl): Make inclusion of descriptor compile time and output + // both of these. Note: Extensions currently have to have the EnumDescription. + (*variables)["enum_verifier"] = type + "_IsValidValue"; + (*variables)["enum_desc_func"] = type + "_EnumDescriptor"; + + const Descriptor* msg_descriptor = descriptor->containing_type(); + (*variables)["owning_message_class"] = ClassName(msg_descriptor); +} +} // namespace + +EnumFieldGenerator::EnumFieldGenerator(const FieldDescriptor* descriptor) + : SingleFieldGenerator(descriptor) { + SetEnumVariables(descriptor, &variables_); +} + +EnumFieldGenerator::~EnumFieldGenerator() {} + +void EnumFieldGenerator::GenerateFieldDescriptionTypeSpecific( + io::Printer* printer) const { + // TODO(thomasvl): Output the CPP check to use descFunc or validator based + // on final compile. + printer->Print( + variables_, + " .typeSpecific.enumDescFunc = $enum_desc_func$,\n"); +} + +void EnumFieldGenerator::GenerateCFunctionDeclarations( + 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" + "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 GPBGetInt32IvarWithField(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" + " GPBSetInt32IvarWithFieldInternal(message, field, value, descriptor.file.syntax);\n" + "}\n" + "\n"); +} + +void EnumFieldGenerator::DetermineForwardDeclarations( + set<string>* fwd_decls) const { + // 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 string& name = variable("storage_type"); + fwd_decls->insert("GPB_ENUM_FWD_DECLARE(" + name + ")"); + } +} + +RepeatedEnumFieldGenerator::RepeatedEnumFieldGenerator( + const FieldDescriptor* descriptor) + : RepeatedFieldGenerator(descriptor) { + SetEnumVariables(descriptor, &variables_); + variables_["array_storage_type"] = "GPBEnumArray"; +} + +RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {} + +void RepeatedEnumFieldGenerator::GenerateFieldDescriptionTypeSpecific( + io::Printer* printer) const { + // TODO(thomasvl): Output the CPP check to use descFunc or validator based + // on final compile. + printer->Print( + variables_, + " .typeSpecific.enumDescFunc = $enum_desc_func$,\n"); +} + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h new file mode 100644 index 00000000..b629eae8 --- /dev/null +++ b/src/google/protobuf/compiler/objectivec/objectivec_enum_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_OBJECTIVEC_ENUM_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_FIELD_H__ + +#include <map> +#include <string> +#include <google/protobuf/compiler/objectivec/objectivec_field.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +class EnumFieldGenerator : public SingleFieldGenerator { + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); + + public: + virtual void GenerateFieldDescriptionTypeSpecific(io::Printer* printer) const; + virtual void GenerateCFunctionDeclarations(io::Printer* printer) const; + virtual void GenerateCFunctionImplementations(io::Printer* printer) const; + virtual void DetermineForwardDeclarations(set<string>* fwd_decls) const; + + protected: + explicit EnumFieldGenerator(const FieldDescriptor* descriptor); + virtual ~EnumFieldGenerator(); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator); +}; + +class RepeatedEnumFieldGenerator : public RepeatedFieldGenerator { + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); + + public: + virtual void GenerateFieldDescriptionTypeSpecific(io::Printer* printer) const; + + protected: + RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor); + virtual ~RepeatedEnumFieldGenerator(); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedEnumFieldGenerator); +}; + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_FIELD_H__ diff --git a/src/google/protobuf/compiler/objectivec/objectivec_extension.cc b/src/google/protobuf/compiler/objectivec/objectivec_extension.cc new file mode 100644 index 00000000..76137c80 --- /dev/null +++ b/src/google/protobuf/compiler/objectivec/objectivec_extension.cc @@ -0,0 +1,165 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (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 <google/protobuf/compiler/objectivec/objectivec_extension.h> +#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/io/printer.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +ExtensionGenerator::ExtensionGenerator(const string& root_class_name, + const FieldDescriptor* descriptor) + : method_name_(ExtensionMethodName(descriptor)), + root_class_and_method_name_(root_class_name + "_" + method_name_), + descriptor_(descriptor) { + // Extensions can be filtered via the method they are accessed off the + // file's Root with. + if (FilterClass(root_class_and_method_name_)) { + filter_reason_ = + string("Extension |") + root_class_and_method_name_ + "| was not whitelisted."; + } else { + // Extensions that add a Message field also require that field be allowed + // by the filter, or they aren't usable. + ObjectiveCType objc_type = GetObjectiveCType(descriptor_); + if (objc_type == OBJECTIVECTYPE_MESSAGE) { + const string message_class_name(ClassName(descriptor_->message_type())); + if (FilterClass(message_class_name)) { + filter_reason_ = string("Extension |") + root_class_and_method_name_ + + "| needs message |" + message_class_name + + "|, which was not whitelisted."; + } + } + } + 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. + cerr << "error: Extension is a map<>!" + << " That used to be blocked by the compiler." << endl; + cerr.flush(); + abort(); + } +} + +ExtensionGenerator::~ExtensionGenerator() {} + +void ExtensionGenerator::GenerateMembersHeader(io::Printer* printer) { + if (IsFiltered()) { + printer->Print("// $filter_reason$\n\n", "filter_reason", filter_reason_); + return; + } + map<string, string> vars; + vars["method_name"] = method_name_; + SourceLocation location; + if (descriptor_->GetSourceLocation(&location)) { + vars["comments"] = BuildCommentsString(location); + } else { + vars["comments"] = ""; + } + printer->Print(vars, + "$comments$" + "+ (GPBExtensionField*)$method_name$;\n"); +} + +void ExtensionGenerator::GenerateStaticVariablesInitialization( + io::Printer* printer, bool* out_generated, bool root) { + if (IsFiltered()) { + return; + } + *out_generated = true; + map<string, string> vars; + vars["root_class_and_method_name"] = root_class_and_method_name_; + vars["extended_type"] = ClassName(descriptor_->containing_type()); + vars["number"] = SimpleItoa(descriptor_->number()); + + std::vector<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(options); + + ObjectiveCType objc_type = GetObjectiveCType(descriptor_); + string singular_type; + if (objc_type == OBJECTIVECTYPE_MESSAGE) { + vars["type"] = string("GPBStringifySymbol(") + + ClassName(descriptor_->message_type()) + ")"; + } else { + vars["type"] = "NULL"; + } + + vars["default_name"] = GPBValueFieldName(descriptor_); + if (descriptor_->is_repeated()) { + vars["default"] = "nil"; + } else { + vars["default"] = DefaultValue(descriptor_); + } + string type = GetCapitalizedType(descriptor_); + vars["extension_type"] = string("GPBType") + 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" + " .singletonName = GPBStringifySymbol($root_class_and_method_name$),\n" + " .type = $extension_type$,\n" + " .extendedClass = GPBStringifySymbol($extended_type$),\n" + " .fieldNumber = $number$,\n" + " .defaultValue.$default_name$ = $default$,\n" + " .messageOrGroupClassName = $type$,\n" + " .options = $options$,\n" + " .enumDescriptorFunc = $enum_desc_func_name$,\n" + "},\n"); +} + +void ExtensionGenerator::GenerateRegistrationSource(io::Printer* printer) { + if (IsFiltered()) { + return; + } + 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/src/google/protobuf/compiler/objectivec/objectivec_extension.h b/src/google/protobuf/compiler/objectivec/objectivec_extension.h new file mode 100644 index 00000000..553f0887 --- /dev/null +++ b/src/google/protobuf/compiler/objectivec/objectivec_extension.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_OBJECTIVEC_EXTENSION_H__ +#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_EXTENSION_H__ + +#include <google/protobuf/stubs/common.h> + +namespace google { +namespace protobuf { +class FieldDescriptor; // descriptor.h +namespace io { +class Printer; // printer.h +} +} + +namespace protobuf { +namespace compiler { +namespace objectivec { + +class ExtensionGenerator { + public: + ExtensionGenerator(const string& root_class_name, + const FieldDescriptor* descriptor); + ~ExtensionGenerator(); + + void GenerateMembersHeader(io::Printer* printer); + void GenerateStaticVariablesInitialization(io::Printer* printer, + bool* out_generated, bool root); + void GenerateRegistrationSource(io::Printer* printer); + + bool IsFiltered() const { return filter_reason_.length() > 0; } + + private: + string method_name_; + string root_class_and_method_name_; + string filter_reason_; + const FieldDescriptor* descriptor_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator); +}; +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_H__ diff --git a/src/google/protobuf/compiler/objectivec/objectivec_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_field.cc new file mode 100644 index 00000000..c5f05653 --- /dev/null +++ b/src/google/protobuf/compiler/objectivec/objectivec_field.cc @@ -0,0 +1,479 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <google/protobuf/compiler/objectivec/objectivec_field.h> +#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> +#include <google/protobuf/compiler/objectivec/objectivec_enum_field.h> +#include <google/protobuf/compiler/objectivec/objectivec_map_field.h> +#include <google/protobuf/compiler/objectivec/objectivec_message_field.h> +#include <google/protobuf/compiler/objectivec/objectivec_primitive_field.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +namespace { +void SetCommonFieldVariables(const FieldDescriptor* descriptor, + map<string, string>* variables) { + string camel_case_name = FieldName(descriptor); + 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 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); + } else { + (*variables)["comments"] = "\n"; + } + const string& classname = ClassName(descriptor->containing_type()); + (*variables)["classname"] = classname; + (*variables)["name"] = camel_case_name; + const 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"] = SimpleItoa(descriptor->number()); + (*variables)["has_index"] = SimpleItoa(descriptor->index()); + (*variables)["field_type"] = GetCapitalizedType(descriptor); + std::vector<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) { + // TODO(thomasvl): Output the CPP check to use descFunc or validator based + // on final compile. + field_flags.push_back("GPBFieldHasEnumDescriptor"); + } + + (*variables)["fieldflags"] = BuildFlagsString(field_flags); + + (*variables)["default"] = DefaultValue(descriptor); + (*variables)["default_name"] = GPBValueFieldName(descriptor); + + (*variables)["typeSpecific_name"] = "className"; + (*variables)["typeSpecific_value"] = "NULL"; + + string field_options = descriptor->options().SerializeAsString(); + // Must convert to a standard byte order for packing length into + // a cstring. + uint32 length = ghtonl(field_options.length()); + if (length > 0) { + string bytes((const char*)&length, sizeof(length)); + bytes.append(field_options); + string options_str = "\"" + CEscape(bytes) + "\""; + (*variables)["fieldoptions"] = "\"" + CEscape(bytes) + "\""; + } else { + (*variables)["fieldoptions"] = ""; + } + + // Clear some common things so they can be set just when needed. + (*variables)["storage_attribute"] = ""; +} + +// A field generator that writes nothing. +class EmptyFieldGenerator : public FieldGenerator { + public: + EmptyFieldGenerator(const FieldDescriptor* descriptor, const string& reason) + : FieldGenerator(descriptor), reason_(reason) {} + virtual ~EmptyFieldGenerator() {} + + virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const {} + virtual void GeneratePropertyDeclaration(io::Printer* printer) const { + string name = FieldName(descriptor_); + string type; + switch (GetObjectiveCType(descriptor_)) { + case OBJECTIVECTYPE_MESSAGE: + type = ClassName(descriptor_->message_type()) + " *"; + break; + + case OBJECTIVECTYPE_ENUM: + type = EnumName(descriptor_->enum_type()) + " "; + break; + + default: + type = string(descriptor_->type_name()) + " "; + break; + } + printer->Print("// Field |$type$$name$| $reason$\n\n", "type", type, "name", + name, "reason", reason_); + } + + virtual void GenerateFieldNumberConstant(io::Printer* printer) const {} + virtual void GeneratePropertyImplementation(io::Printer* printer) const {} + virtual void GenerateFieldDescription(io::Printer* printer) const {} + + virtual bool WantsHasProperty(void) const { return false; } + + private: + string reason_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EmptyFieldGenerator); +}; + +} // namespace + +FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field) { + FieldGenerator* result = NULL; + if (field->is_repeated()) { + switch (GetObjectiveCType(field)) { + case OBJECTIVECTYPE_MESSAGE: { + string type = ClassName(field->message_type()); + if (FilterClass(type)) { + string reason = + "Filtered by |" + type + "| not being whitelisted."; + result = new EmptyFieldGenerator(field, reason); + } else if (field->is_map()) { + result = new MapFieldGenerator(field); + } else { + result = new RepeatedMessageFieldGenerator(field); + } + break; + } + case OBJECTIVECTYPE_ENUM: + result = new RepeatedEnumFieldGenerator(field); + break; + default: + result = new RepeatedPrimitiveFieldGenerator(field); + break; + } + } else { + switch (GetObjectiveCType(field)) { + case OBJECTIVECTYPE_MESSAGE: { + string type = ClassName(field->message_type()); + if (FilterClass(type)) { + string reason = + "Filtered by |" + type + "| not being whitelisted."; + result = new EmptyFieldGenerator(field, reason); + } else { + result = new MessageFieldGenerator(field); + } + break; + } + case OBJECTIVECTYPE_ENUM: + result = new EnumFieldGenerator(field); + break; + default: + if (IsReferenceType(field)) { + result = new PrimitiveObjFieldGenerator(field); + } else { + result = new PrimitiveFieldGenerator(field); + } + break; + } + } + result->FinishInitialization(); + return result; +} + + +FieldGenerator::FieldGenerator(const FieldDescriptor* descriptor) + : 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( + set<string>* fwd_decls) const { + // Nothing +} + +void FieldGenerator::GenerateFieldDescription( + io::Printer* printer) const { + printer->Print( + variables_, + "{\n" + " .name = \"$name$\",\n" + " .number = $field_number_name$,\n" + " .hasIndex = $has_index$,\n" + " .flags = $fieldflags$,\n" + " .type = GPBType$field_type$,\n" + " .offset = offsetof($classname$_Storage, $name$),\n" + " .defaultValue.$default_name$ = $default$,\n"); + + // " .typeSpecific.value* = [something]," + GenerateFieldDescriptionTypeSpecific(printer); + + const string& field_options(variables_.find("fieldoptions")->second); + if (field_options.empty()) { + printer->Print(" .fieldOptions = NULL,\n"); + } else { + // Can't use PrintRaw() here to get the #if/#else/#endif lines completely + // outdented because the need for indent captured on the previous + // printing of a \n and there is no way to get the current indent level + // to call the right number of Outdent()/Indents() to maintain state. + printer->Print( + variables_, + "#if GPBOBJC_INCLUDE_FIELD_OPTIONS\n" + " .fieldOptions = $fieldoptions$,\n" + "#else\n" + " .fieldOptions = NULL,\n" + "#endif // GPBOBJC_INCLUDE_FIELD_OPTIONS\n"); + } + + printer->Print("},\n"); +} + +void FieldGenerator::GenerateFieldDescriptionTypeSpecific( + io::Printer* printer) const { + printer->Print( + variables_, + " .typeSpecific.$typeSpecific_name$ = $typeSpecific_value$,\n"); +} + +void FieldGenerator::SetOneofIndexBase(int index_base) { + if (descriptor_->containing_oneof() != NULL) { + int index = descriptor_->containing_oneof()->index() + index_base; + // Flip the sign to mark it as a oneof. + variables_["has_index"] = SimpleItoa(-index); + } +} + +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) + : FieldGenerator(descriptor) { + // 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$"); + if (WantsHasProperty()) { + printer->Print( + variables_, + "@property(nonatomic, readwrite) BOOL has$capitalized_name$;\n"); + } + printer->Print( + variables_, + "@property(nonatomic, readwrite) $property_type$ $name$;\n" + "\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::WantsHasProperty(void) const { + if (descriptor_->containing_oneof() != NULL) { + // If in a oneof, it uses the oneofcase instead of a has bit. + return false; + } + if (HasFieldPresence(descriptor_->file())) { + // In proto1/proto2, every field has a has_$name$() method. + return true; + } + return false; +} + +ObjCObjFieldGenerator::ObjCObjFieldGenerator( + const FieldDescriptor* descriptor) + : SingleFieldGenerator(descriptor) { + 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$"); + if (WantsHasProperty()) { + printer->Print( + variables_, + "@property(nonatomic, readwrite) BOOL has$capitalized_name$;\n"); + } + printer->Print( + variables_, + "@property(nonatomic, readwrite, $property_storage_attribute$) $property_type$ *$name$$storage_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;\n"); + } + printer->Print("\n"); +} + +RepeatedFieldGenerator::RepeatedFieldGenerator( + const FieldDescriptor* descriptor) + : ObjCObjFieldGenerator(descriptor) { + // Repeated fields don't use the has index. + variables_["has_index"] = "GPBNoHasBit"; +} + +RepeatedFieldGenerator::~RepeatedFieldGenerator() {} + +void RepeatedFieldGenerator::FinishInitialization(void) { + FieldGenerator::FinishInitialization(); + variables_["array_comment"] = + "// |" + variables_["name"] + "| contains |" + variables_["storage_type"] + "|\n"; +} + +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$;\n"); +} + +void RepeatedFieldGenerator::GeneratePropertyDeclaration( + io::Printer* printer) const { + + // Repeated fields don't need the has* properties, but this has 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) $array_storage_type$ *$name$$storage_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_storage_type$ *)$name$ GPB_METHOD_FAMILY_NONE;\n"); + } + printer->Print("\n"); +} + +bool RepeatedFieldGenerator::WantsHasProperty(void) const { + // Consumer check the array size/existance rather than a has bit. + return false; +} + +FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor) + : descriptor_(descriptor), + field_generators_( + new scoped_ptr<FieldGenerator>[descriptor->field_count()]), + extension_generators_( + new scoped_ptr<FieldGenerator>[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))); + } + for (int i = 0; i < descriptor->extension_count(); i++) { + extension_generators_[i].reset(FieldGenerator::Make(descriptor->extension(i))); + } +} + +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]; +} + +void FieldGeneratorMap::SetOneofIndexBase(int index_base) { + for (int i = 0; i < descriptor_->field_count(); i++) { + field_generators_[i]->SetOneofIndexBase(index_base); + } +} + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/objectivec/objectivec_field.h b/src/google/protobuf/compiler/objectivec/objectivec_field.h new file mode 100644 index 00000000..130a52dd --- /dev/null +++ b/src/google/protobuf/compiler/objectivec/objectivec_field.h @@ -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. + +#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FIELD_H__ + +#include <map> +#include <string> +#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/descriptor.h> + +namespace google { +namespace protobuf { + +namespace io { +class Printer; // printer.h +} // namespace io + +namespace compiler { +namespace objectivec { + +class FieldGenerator { + public: + static FieldGenerator* Make(const FieldDescriptor* field); + + virtual ~FieldGenerator(); + + virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const = 0; + virtual void GeneratePropertyDeclaration(io::Printer* printer) const = 0; + + virtual void GeneratePropertyImplementation(io::Printer* printer) const = 0; + + virtual void GenerateFieldDescription(io::Printer* printer) const; + virtual void GenerateFieldDescriptionTypeSpecific(io::Printer* printer) const; + virtual void GenerateFieldNumberConstant(io::Printer* printer) const; + + virtual void GenerateCFunctionDeclarations(io::Printer* printer) const; + virtual void GenerateCFunctionImplementations(io::Printer* printer) const; + + virtual void DetermineForwardDeclarations(set<string>* fwd_decls) const; + + void SetOneofIndexBase(int index_base); + + string variable(const char* key) const { + return variables_.find(key)->second; + } + + bool needs_textformat_name_support() const { + const string& field_flags = variable("fieldflags"); + return field_flags.find("GPBFieldTextFormatNameCustom") != string::npos; + } + string generated_objc_name() const { return variable("name"); } + string raw_field_name() const { return variable("raw_field_name"); } + + protected: + explicit FieldGenerator(const FieldDescriptor* descriptor); + + virtual void FinishInitialization(void); + virtual bool WantsHasProperty(void) const = 0; + + const FieldDescriptor* descriptor_; + map<string, string> variables_; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGenerator); +}; + +class SingleFieldGenerator : public FieldGenerator { + public: + virtual ~SingleFieldGenerator(); + + virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const; + virtual void GeneratePropertyDeclaration(io::Printer* printer) const; + + virtual void GeneratePropertyImplementation(io::Printer* printer) const; + + protected: + explicit SingleFieldGenerator(const FieldDescriptor* descriptor); + virtual bool WantsHasProperty(void) const; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SingleFieldGenerator); +}; + +// Subclass with common support for when the field ends up as an ObjC Object. +class ObjCObjFieldGenerator : public SingleFieldGenerator { + public: + virtual ~ObjCObjFieldGenerator(); + + virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const; + virtual void GeneratePropertyDeclaration(io::Printer* printer) const; + + protected: + explicit ObjCObjFieldGenerator(const FieldDescriptor* descriptor); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ObjCObjFieldGenerator); +}; + +class RepeatedFieldGenerator : public ObjCObjFieldGenerator { + public: + virtual ~RepeatedFieldGenerator(); + + virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const; + virtual void GeneratePropertyDeclaration(io::Printer* printer) const; + + virtual void GeneratePropertyImplementation(io::Printer* printer) const; + + protected: + explicit RepeatedFieldGenerator(const FieldDescriptor* descriptor); + virtual void FinishInitialization(void); + virtual bool WantsHasProperty(void) const; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedFieldGenerator); +}; + +// Convenience class which constructs FieldGenerators for a Descriptor. +class FieldGeneratorMap { + public: + explicit FieldGeneratorMap(const Descriptor* descriptor); + ~FieldGeneratorMap(); + + const FieldGenerator& get(const FieldDescriptor* field) const; + const FieldGenerator& get_extension(int index) const; + + void SetOneofIndexBase(int index_base); + + private: + const Descriptor* descriptor_; + scoped_array<scoped_ptr<FieldGenerator> > field_generators_; + scoped_array<scoped_ptr<FieldGenerator> > extension_generators_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap); +}; +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FIELD_H__ diff --git a/src/google/protobuf/compiler/objectivec/objectivec_file.cc b/src/google/protobuf/compiler/objectivec/objectivec_file.cc new file mode 100644 index 00000000..d04eee85 --- /dev/null +++ b/src/google/protobuf/compiler/objectivec/objectivec_file.cc @@ -0,0 +1,409 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <google/protobuf/compiler/objectivec/objectivec_file.h> +#include <google/protobuf/compiler/objectivec/objectivec_enum.h> +#include <google/protobuf/compiler/objectivec/objectivec_extension.h> +#include <google/protobuf/compiler/objectivec/objectivec_message.h> +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/stubs/stl_util.h> +#include <google/protobuf/stubs/strutil.h> +#include <sstream> + +namespace google { +namespace protobuf { + +// This is also found in GPBBootstrap.h, and needs to be kept in sync. It +// is the version check done to ensure generated code works with the current +// runtime being used. +const int32 GOOGLE_PROTOBUF_OBJC_GEN_VERSION = 30000; + +namespace compiler { +namespace objectivec { + +FileGenerator::FileGenerator(const FileDescriptor *file) + : file_(file), + root_class_name_(FileClassName(file)), + is_filtered_(true), + all_extensions_filtered_(true), + is_public_dep_(false) { + // Validate the objc prefix, do this even if the file's contents are filtered + // to catch a bad prefix as soon as it is found. + ValidateObjCClassPrefix(file_); + + for (int i = 0; i < file_->enum_type_count(); i++) { + EnumGenerator *generator = new EnumGenerator(file_->enum_type(i)); + // The enums are exposed via C functions, so they will dead strip if + // not used. + is_filtered_ &= false; + enum_generators_.push_back(generator); + } + for (int i = 0; i < file_->message_type_count(); i++) { + MessageGenerator *generator = + new MessageGenerator(root_class_name_, file_->message_type(i)); + is_filtered_ &= generator->IsFiltered(); + is_filtered_ &= generator->IsSubContentFiltered(); + message_generators_.push_back(generator); + } + for (int i = 0; i < file_->extension_count(); i++) { + ExtensionGenerator *generator = + new ExtensionGenerator(root_class_name_, file_->extension(i)); + is_filtered_ &= generator->IsFiltered(); + all_extensions_filtered_ &= generator->IsFiltered(); + extension_generators_.push_back(generator); + } + // If there is nothing in the file we filter it. +} + +FileGenerator::~FileGenerator() { + STLDeleteContainerPointers(dependency_generators_.begin(), + dependency_generators_.end()); + STLDeleteContainerPointers(enum_generators_.begin(), enum_generators_.end()); + STLDeleteContainerPointers(message_generators_.begin(), + message_generators_.end()); + STLDeleteContainerPointers(extension_generators_.begin(), + extension_generators_.end()); +} + +void FileGenerator::GenerateHeader(io::Printer *printer) { + printer->Print( + "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" + "// source: $filename$\n" + "\n", + "filename", file_->name()); + + printer->Print( + "#import \"GPBProtocolBuffers.h\"\n" + "\n"); + + // Add some verification that the generated code matches the source the + // code is being compiled with. + printer->Print( + "#if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != $protoc_gen_objc_version$\n" + "#error This file was generated by a different version of protoc-gen-objc which is incompatible with your Protocol Buffer sources.\n" + "#endif\n" + "\n", + "protoc_gen_objc_version", + SimpleItoa(GOOGLE_PROTOBUF_OBJC_GEN_VERSION)); + + const vector<FileGenerator *> &dependency_generators = + DependencyGenerators(); + for (vector<FileGenerator *>::const_iterator iter = + dependency_generators.begin(); + iter != dependency_generators.end(); ++iter) { + if ((*iter)->IsPublicDependency()) { + printer->Print("#import \"$header$.pbobjc.h\"\n", + "header", (*iter)->Path()); + } + } + + printer->Print( + "// @@protoc_insertion_point(imports)\n" + "\n"); + + printer->Print("CF_EXTERN_C_BEGIN\n\n"); + + if (!IsFiltered()) { + set<string> fwd_decls; + for (vector<MessageGenerator *>::iterator iter = message_generators_.begin(); + iter != message_generators_.end(); ++iter) { + (*iter)->DetermineForwardDeclarations(&fwd_decls); + } + for (set<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"); + } + } + + // need to write out all enums first + for (vector<EnumGenerator *>::iterator iter = enum_generators_.begin(); + iter != enum_generators_.end(); ++iter) { + (*iter)->GenerateHeader(printer); + } + + for (vector<MessageGenerator *>::iterator iter = message_generators_.begin(); + iter != message_generators_.end(); ++iter) { + (*iter)->GenerateEnumHeader(printer); + } + + // For extensions to chain together, the Root gets created even if there + // are no extensions. So if the entire file isn't filtered away, output it. + if (!IsFiltered()) { + printer->Print( + "\n" + "#pragma mark - $root_class_name$\n" + "\n" + "@interface $root_class_name$ : GPBRootObject\n" + "\n" + "// The base class provides:\n" + "// + (GPBExtensionRegistry *)extensionRegistry;\n" + "// which is an GPBExtensionRegistry that includes all the extensions defined by\n" + "// this file and all files that it depends on.\n" + "\n" + "@end\n" + "\n", + "root_class_name", root_class_name_); + } + + if (extension_generators_.size() > 0) { + // The dynamic methods block is only needed if there are extensions. If + // they are all filtered, output the @interface as a comment so there is + // something left in the header for anyone that looks. + const char *root_line_prefix = ""; + if (AreAllExtensionsFiltered()) { + root_line_prefix = "// "; + } + printer->Print( + "$root_line_prefix$@interface $root_class_name$ (DynamicMethods)\n", + "root_class_name", root_class_name_, + "root_line_prefix", root_line_prefix); + + for (vector<ExtensionGenerator *>::iterator iter = + extension_generators_.begin(); + iter != extension_generators_.end(); ++iter) { + (*iter)->GenerateMembersHeader(printer); + } + + printer->Print("$root_line_prefix$@end\n\n", + "root_line_prefix", root_line_prefix); + } // extension_generators_.size() > 0 + + for (vector<MessageGenerator *>::iterator iter = message_generators_.begin(); + iter != message_generators_.end(); ++iter) { + (*iter)->GenerateMessageHeader(printer); + } + + printer->Print("CF_EXTERN_C_END\n"); + + printer->Print( + "\n" + "// @@protoc_insertion_point(global_scope)\n"); +} + +void FileGenerator::GenerateSource(io::Printer *printer) { + printer->Print( + "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" + "// source: $filename$\n" + "\n", + "filename", file_->name()); + + string header_file = Path() + ".pbobjc.h"; + printer->Print( + "#import \"GPBProtocolBuffers_RuntimeSupport.h\"\n" + "#import \"$header_file$\"\n", + "header_file", header_file); + const vector<FileGenerator *> &dependency_generators = + DependencyGenerators(); + for (vector<FileGenerator *>::const_iterator iter = + dependency_generators.begin(); + iter != dependency_generators.end(); ++iter) { + if (!(*iter)->IsPublicDependency()) { + printer->Print("#import \"$header$.pbobjc.h\"\n", + "header", (*iter)->Path()); + } + } + printer->Print( + "// @@protoc_insertion_point(imports)\n" + "\n"); + + if (IsFiltered()) { + printer->Print( + "// File empty because all messages, extensions and enum have been filtered.\n" + "\n" + "\n" + "// Dummy symbol that will be stripped but will avoid linker warnings about\n" + "// no symbols in the .o form compiling this file.\n" + "static int $root_class_name$_dummy __attribute__((unused,used)) = 0;\n" + "\n" + "// @@protoc_insertion_point(global_scope)\n", + "root_class_name", root_class_name_); + return; + } + + printer->Print( + "#pragma mark - $root_class_name$\n" + "\n" + "@implementation $root_class_name$\n\n", + "root_class_name", root_class_name_); + + bool generated_extensions = false; + if (file_->extension_count() + file_->message_type_count() + + file_->dependency_count() > + 0) { + ostringstream extensions_stringstream; + + if (file_->extension_count() + file_->message_type_count() > 0) { + io::OstreamOutputStream extensions_outputstream(&extensions_stringstream); + io::Printer extensions_printer(&extensions_outputstream, '$'); + extensions_printer.Print( + "static GPBExtensionDescription descriptions[] = {\n"); + extensions_printer.Indent(); + for (vector<ExtensionGenerator *>::iterator iter = + extension_generators_.begin(); + iter != extension_generators_.end(); ++iter) { + (*iter)->GenerateStaticVariablesInitialization( + &extensions_printer, &generated_extensions, true); + } + for (vector<MessageGenerator *>::iterator iter = + message_generators_.begin(); + iter != message_generators_.end(); ++iter) { + (*iter)->GenerateStaticVariablesInitialization(&extensions_printer, + &generated_extensions); + } + extensions_printer.Outdent(); + extensions_printer.Print("};\n"); + if (generated_extensions) { + extensions_printer.Print( + "for (size_t i = 0; i < sizeof(descriptions) / sizeof(descriptions[0]); ++i) {\n" + " GPBExtensionField *extension = [[GPBExtensionField alloc] initWithDescription:&descriptions[i]];\n" + " [registry addExtension:extension];\n" + " [self globallyRegisterExtension:extension];\n" + " [extension release];\n" + "}\n"); + } else { + extensions_printer.Print("#pragma unused (descriptions)\n"); + } + const vector<FileGenerator *> &dependency_generators = + DependencyGenerators(); + if (dependency_generators.size()) { + for (vector<FileGenerator *>::const_iterator iter = + dependency_generators.begin(); + iter != dependency_generators.end(); ++iter) { + if (!(*iter)->IsFiltered()) { + extensions_printer.Print( + "[registry addExtensions:[$dependency$ extensionRegistry]];\n", + "dependency", (*iter)->RootClassName()); + generated_extensions = true; + } + } + } else if (!generated_extensions) { + extensions_printer.Print("#pragma unused (registry)\n"); + } + } + + if (generated_extensions) { + 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" + " registry = [[GPBExtensionRegistry alloc] init];\n"); + + printer->Indent(); + printer->Indent(); + + extensions_stringstream.flush(); + printer->Print(extensions_stringstream.str().c_str()); + printer->Outdent(); + printer->Outdent(); + + printer->Print( + " }\n" + " return registry;\n" + "}\n" + "\n"); + } + } + + printer->Print("@end\n\n"); + + + string syntax; + switch (file_->syntax()) { + case FileDescriptor::SYNTAX_UNKNOWN: + syntax = "GPBFileSyntaxUnknown"; + break; + case FileDescriptor::SYNTAX_PROTO2: + syntax = "GPBFileSyntaxProto2"; + break; + case FileDescriptor::SYNTAX_PROTO3: + syntax = "GPBFileSyntaxProto3"; + break; + } + printer->Print( + "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" + " descriptor = [[GPBFileDescriptor alloc] initWithPackage:@\"$package$\"\n" + " syntax:$syntax$];\n" + " }\n" + " return descriptor;\n" + "}\n" + "\n", + "root_class_name", root_class_name_, + "package", file_->package(), + "syntax", syntax); + + for (vector<EnumGenerator *>::iterator iter = enum_generators_.begin(); + iter != enum_generators_.end(); ++iter) { + (*iter)->GenerateSource(printer); + } + for (vector<MessageGenerator *>::iterator iter = message_generators_.begin(); + iter != message_generators_.end(); ++iter) { + (*iter)->GenerateSource(printer); + } + + printer->Print( + "\n" + "// @@protoc_insertion_point(global_scope)\n"); +} + +const string FileGenerator::Path() const { return FilePath(file_); } + +const vector<FileGenerator *> &FileGenerator::DependencyGenerators() { + if (file_->dependency_count() != dependency_generators_.size()) { + set<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++) { + FileGenerator *generator = new FileGenerator(file_->dependency(i)); + const string& name = file_->dependency(i)->name(); + bool public_import = (public_import_names.count(name) != 0); + generator->SetIsPublicDependency(public_import); + dependency_generators_.push_back(generator); + } + } + return dependency_generators_; +} + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/objectivec/objectivec_file.h b/src/google/protobuf/compiler/objectivec/objectivec_file.h new file mode 100644 index 00000000..95d17bfd --- /dev/null +++ b/src/google/protobuf/compiler/objectivec/objectivec_file.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_COMPILER_OBJECTIVEC_FILE_H__ +#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FILE_H__ + +#include <string> +#include <set> +#include <vector> +#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> +#include <google/protobuf/stubs/common.h> + +namespace google { +namespace protobuf { +class FileDescriptor; // descriptor.h +namespace io { +class Printer; // printer.h +} +} + +namespace protobuf { +namespace compiler { +namespace objectivec { + +class EnumGenerator; +class ExtensionGenerator; +class MessageGenerator; + +class FileGenerator { + public: + explicit FileGenerator(const FileDescriptor* file); + ~FileGenerator(); + + void GenerateSource(io::Printer* printer); + void GenerateHeader(io::Printer* printer); + + const string& RootClassName() const { return root_class_name_; } + const string Path() const; + + bool IsFiltered() const { return is_filtered_; } + bool AreAllExtensionsFiltered() const { return all_extensions_filtered_; } + bool IsPublicDependency() const { return is_public_dep_; } + + protected: + void SetIsPublicDependency(bool is_public_dep) { + is_public_dep_ = is_public_dep; + } + + private: + const FileDescriptor* file_; + string root_class_name_; + + // Access this field through the DependencyGenerators accessor call below. + // Do not reference it directly. + vector<FileGenerator*> dependency_generators_; + + vector<EnumGenerator*> enum_generators_; + vector<MessageGenerator*> message_generators_; + vector<ExtensionGenerator*> extension_generators_; + bool is_filtered_; + bool all_extensions_filtered_; + bool is_public_dep_; + + const vector<FileGenerator*>& DependencyGenerators(); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator); +}; + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FILE_H__ diff --git a/src/google/protobuf/compiler/objectivec/objectivec_generator.cc b/src/google/protobuf/compiler/objectivec/objectivec_generator.cc new file mode 100644 index 00000000..17776715 --- /dev/null +++ b/src/google/protobuf/compiler/objectivec/objectivec_generator.cc @@ -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. + +#include <iostream> +#include <google/protobuf/compiler/objectivec/objectivec_generator.h> +#include <google/protobuf/compiler/objectivec/objectivec_file.h> +#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +ObjectiveCGenerator::ObjectiveCGenerator() {} + +ObjectiveCGenerator::~ObjectiveCGenerator() {} + +bool ObjectiveCGenerator::Generate(const FileDescriptor* file, + const string& parameter, + OutputDirectory* output_directory, + string* error) const { + // ObjC doesn't have any options at the moment, error if passed one. + vector<pair<string, string> > options; + ParseGeneratorParameter(parameter, &options); + for (int i = 0; i < options.size(); i++) { + *error = "error:: Unknown generator option: " + options[i].first; + return false; + } + + if (!InitializeClassWhitelist(error)) { + return false; + } + + FileGenerator file_generator(file); + + string filepath = FilePath(file); + + // Generate header. + { + scoped_ptr<io::ZeroCopyOutputStream> output( + output_directory->Open(filepath + ".pbobjc.h")); + io::Printer printer(output.get(), '$'); + file_generator.GenerateHeader(&printer); + } + + // Generate m file. + { + scoped_ptr<io::ZeroCopyOutputStream> output( + output_directory->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/src/google/protobuf/compiler/objectivec/objectivec_generator.h b/src/google/protobuf/compiler/objectivec/objectivec_generator.h new file mode 100644 index 00000000..24286ac9 --- /dev/null +++ b/src/google/protobuf/compiler/objectivec/objectivec_generator.h @@ -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. + +// 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 <google/protobuf/compiler/code_generator.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +class LIBPROTOC_EXPORT ObjectiveCGenerator : public CodeGenerator { + public: + ObjectiveCGenerator(); + ~ObjectiveCGenerator(); + + // implements CodeGenerator ---------------------------------------- + bool Generate(const FileDescriptor* file, const string& parameter, + OutputDirectory* output_directory, string* error) const; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ObjectiveCGenerator); +}; +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_GENERATOR_H__ diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc new file mode 100644 index 00000000..6d6e5959 --- /dev/null +++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc @@ -0,0 +1,1099 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (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 <sstream> +#include <vector> + +#include <google/protobuf/stubs/hash.h> +#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/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 { + +namespace { + +hash_set<string> gClassWhitelist; + +// islower()/isupper()/tolower()/toupper() change based on locale. +// +// src/google/protobuf/stubs/strutil.h:150 has the same pattern. For the +// Objective C plugin, test failures were seen on TravisCI because isupper('A') +// was coming back false for some server's locale. This approach avoids any +// such issues. + +bool IsLower(const char c) { + return ('a' <= c && c <= 'z'); +} + +bool IsUpper(const char c) { + return ('A' <= c && c <= 'Z'); +} + +char ToLower(char c) { + if ('A' <= c && c <= 'Z') { + c += 'a' - 'A'; + } + return c; +} + +// toupper() changes based on locale. We don't want this! +char ToUpper(char c) { + if ('a' <= c && c <= 'z') { + c += 'A' - 'a'; + } + return c; +} + +string TrimString(const string& s) { + string::size_type start = s.find_first_not_of(" \n\r\t"); + if (start == string::npos) { + return ""; + } + string::size_type end = s.find_last_not_of(" \n\r\t") + 1; + return s.substr(start, end - start); +} + +hash_set<string> MakeWordsMap(const char* const words[], size_t num_words) { + hash_set<string> result; + for (int i = 0; i < num_words; i++) { + result.insert(words[i]); + } + return result; +} + +const char* const kUpperSegmentsList[] = {"url", "http", "https"}; + +hash_set<string> kUpperSegments = + MakeWordsMap(kUpperSegmentsList, GOOGLE_ARRAYSIZE(kUpperSegmentsList)); + +// 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. +string UnderscoresToCamelCase(const string& input, bool first_capitalized) { + vector<string> values; + 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 (c >= '0' && c <= '9') { + 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 (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 (IsUpper(c)) { + if (!last_char_was_upper) { + values.push_back(current); + current = ""; + } + current += 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); + + for (vector<string>::iterator i = values.begin(); i != values.end(); ++i) { + string value = *i; + bool all_upper = (kUpperSegments.count(value) > 0); + for (int j = 0; j < value.length(); j++) { + if (j == 0 || all_upper) { + value[j] = ToUpper(value[j]); + } else { + // Nothing, already in lower. + } + } + *i = value; + } + string result; + for (vector<string>::iterator i = values.begin(); i != values.end(); ++i) { + result += *i; + } + if ((result.length() != 0) && !first_capitalized) { + result[0] = ToLower(result[0]); + } + return result; +} + +const char* const kReservedWordList[] = { + // Objective C "keywords" that aren't in C + // From + // http://stackoverflow.com/questions/1873630/reserved-keywords-in-objective-c + "id", "_cmd", "super", "in", "out", "inout", "bycopy", "byref", "oneway", + "self", + + // 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", + + // Objective-C Runtime typedefs + // From <obc/runtime.h> + "Category", "Ivar", "Method", "Protocol", + + // NSObject Methods + // new is covered by C++ keywords. + "description", "debugDescription", "finalize", "hash", "dealloc", "init", + "class", "superclass", "retain", "release", "autorelease", "retainCount", + "zone", "isProxy", "copy", "mutableCopy", "classForCoder", + + // 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", "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", +}; + +hash_set<string> kReservedWords = + MakeWordsMap(kReservedWordList, GOOGLE_ARRAYSIZE(kReservedWordList)); + +string SanitizeNameForObjC(const string& input, const string& extension) { + if (kReservedWords.count(input) > 0) { + return input + extension; + } + return input; +} + +string NameFromFieldDescriptor(const FieldDescriptor* field) { + if (field->type() == FieldDescriptor::TYPE_GROUP) { + return field->message_type()->name(); + } else { + return field->name(); + } +} + +// Escape C++ trigraphs by escaping question marks to \? +string EscapeTrigraphs(const string& to_escape) { + return StringReplace(to_escape, "?", "\\?", true); +} + +void PathSplit(const string& path, string* directory, string* basename) { + string::size_type last_slash = path.rfind('/'); + if (last_slash == 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 string& name, const 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 !IsLower(name[length]); + } else { + return true; + } + } + } + return false; +} + +} // namespace + +string StripProto(const string& filename) { + if (HasSuffixString(filename, ".protodevel")) { + return StripSuffixString(filename, ".protodevel"); + } else { + return StripSuffixString(filename, ".proto"); + } +} + +bool IsRetainedName(const string& name) { + // List of prefixes from + // http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html + static const string retained_names[] = {"new", "alloc", "copy", + "mutableCopy"}; + return IsSpecialName(name, retained_names, + sizeof(retained_names) / sizeof(retained_names[0])); +} + +bool IsInitName(const string& name) { + static const string init_names[] = {"init"}; + return IsSpecialName(name, init_names, + sizeof(init_names) / sizeof(init_names[0])); +} + +string BaseFileName(const FileDescriptor* file) { + string basename; + PathSplit(file->name(), NULL, &basename); + return basename; +} + +string FileName(const FileDescriptor* file) { + string path = FilePath(file); + string basename; + PathSplit(path, NULL, &basename); + return basename; +} + +string FilePath(const FileDescriptor* file) { + string output; + string basename; + 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; +} + +string FileClassPrefix(const FileDescriptor* file) { + // Default is empty string, no need to check has_objc_class_prefix. + string result = file->options().objc_class_prefix(); + return result; +} + +void ValidateObjCClassPrefix(const FileDescriptor* file) { + string prefix = file->options().objc_class_prefix(); + if (prefix.length() > 0) { + // 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. + if (!IsUpper(prefix[0])) { + cerr << endl + << "protoc:0: warning: Invalid 'option objc_class_prefix = \"" + << prefix << "\";' in '" << file->name() << "';" + << " it should start with a capital letter." + << endl; + cerr.flush(); + } + if (prefix.length() < 3) { + cerr << endl + << "protoc:0: warning: Invalid 'option objc_class_prefix = \"" + << prefix << "\";' in '" << file->name() << "';" + << " Apple recommends they should be at least 3 characters long." + << endl; + cerr.flush(); + } + } +} + +string FileClassName(const FileDescriptor* file) { + string name = FileClassPrefix(file); + name += UnderscoresToCamelCase(StripProto(BaseFileName(file)), true); + name += "Root"; + // There aren't really any reserved words that end in "Root", but playing + // it safe and checking. + return SanitizeNameForObjC(name, "_RootClass"); +} + +string ClassNameWorker(const Descriptor* descriptor) { + string name; + if (descriptor->containing_type() != NULL) { + name = ClassNameWorker(descriptor->containing_type()); + name += "_"; + } + return name + descriptor->name(); +} + +string ClassNameWorker(const EnumDescriptor* descriptor) { + string name; + if (descriptor->containing_type() != NULL) { + name = ClassNameWorker(descriptor->containing_type()); + name += "_"; + } + return name + descriptor->name(); +} + +string ClassName(const Descriptor* descriptor) { + // 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. + string prefix = FileClassPrefix(descriptor->file()); + string name = ClassNameWorker(descriptor); + return SanitizeNameForObjC(prefix + name, "_Class"); +} + +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. + string name = FileClassPrefix(descriptor->file()); + name += ClassNameWorker(descriptor); + return SanitizeNameForObjC(name, "_Enum"); +} + +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 string& class_name = EnumName(descriptor->type()); + const string& value_str = UnderscoresToCamelCase(descriptor->name(), true); + const 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"); +} + +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 string& class_name = EnumName(descriptor->type()); + const string& long_name_prefix = class_name + "_"; + const string& long_name = EnumValueName(descriptor); + return StripPrefixString(long_name, long_name_prefix); +} + +string UnCamelCaseEnumShortName(const string& name) { + string result; + for (int i = 0; i < name.size(); i++) { + char c = name[i]; + if (i > 0 && c >= 'A' && c <= 'Z') { + result += '_'; + } + result += ToUpper(c); + } + return result; +} + +string ExtensionMethodName(const FieldDescriptor* descriptor) { + const string& name = NameFromFieldDescriptor(descriptor); + const string& result = UnderscoresToCamelCase(name, false); + return SanitizeNameForObjC(result, "_Extension"); +} + +string FieldName(const FieldDescriptor* field) { + const string& name = NameFromFieldDescriptor(field); + 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"); +} + +string FieldNameCapitalized(const FieldDescriptor* field) { + // Want the same suffix handling, so upcase the first letter of the other + // name. + string result = FieldName(field); + if (result.length() > 0) { + result[0] = ToUpper(result[0]); + } + return result; +} + +string OneofEnumName(const OneofDescriptor* descriptor) { + const Descriptor* fieldDescriptor = descriptor->containing_type(); + 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; +} + +string OneofName(const OneofDescriptor* descriptor) { + string name = UnderscoresToCamelCase(descriptor->name(), false); + // No sanitize needed because it gets OneOfCase added and that shouldn't + // ever conflict. + return name; +} + +string OneofNameCapitalized(const OneofDescriptor* descriptor) { + // Use the common handling and then up-case the first letter. + string result = OneofName(descriptor); + if (result.length() > 0) { + result[0] = ToUpper(result[0]); + } + return result; +} + +string UnCamelCaseFieldName(const string& name, const FieldDescriptor* field) { + 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 (worker[0] >= 'a' && worker[0] <= 'z') { + worker[0] = ToUpper(worker[0]); + } + } + return worker; + } else { + string result; + for (int i = 0; i < worker.size(); i++) { + char c = worker[i]; + if (c >= 'A' && c <= 'Z') { + if (i > 0) { + result += '_'; + } + result += ToLower(c); + } else { + result += c; + } + } + return result; + } +} + +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 "Data"; + 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 NULL; +} + +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 string HandleExtremeFloatingPoint(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(".") != string::npos || val.find("e") != string::npos || + val.find("E") != string::npos)) { + val += "f"; + } + return val; + } +} + +string GPBValueFieldName(const FieldDescriptor* field) { + // Returns the field within the GPBValue 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 NULL; +} + + +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 SimpleItoa(field->default_value_int32()); + case FieldDescriptor::CPPTYPE_UINT32: + return SimpleItoa(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 SimpleItoa(field->default_value_int64()) + "LL"; + case FieldDescriptor::CPPTYPE_UINT64: + return SimpleItoa(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 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 length = ghtonl(default_string.length()); + string bytes((const char*)&length, sizeof(length)); + bytes.append(default_string); + return "(NSData*)\"" + 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 NULL; +} + +string BuildFlagsString(const vector<string>& strings) { + if (strings.size() == 0) { + return "0"; + } + string string; + for (size_t i = 0; i != strings.size(); ++i) { + if (i > 0) { + string.append(" | "); + } + string.append(strings[i]); + } + return string; +} + +string BuildCommentsString(const SourceLocation& location) { + const string& comments = location.leading_comments.empty() + ? location.trailing_comments + : location.leading_comments; + vector<string> lines; + SplitStringAllowEmpty(comments, "\n", &lines); + while (!lines.empty() && lines.back().empty()) { + lines.pop_back(); + } + string prefix("//"); + string suffix("\n"); + string final_comments; + for (int i = 0; i < lines.size(); i++) { + // We use $ for delimiters, so replace comments with dollars with + // html escaped version. + // None of the other compilers handle this (as of this writing) but we + // ran into it once, so just to be safe. + final_comments += + prefix + StringReplace(lines[i], "$", "$", true) + suffix; + } + return final_comments; +} + +bool InitializeClassWhitelist(string* error) { + const char* env_var_value = getenv("GPB_OBJC_CLASS_WHITELIST_PATHS"); + if (env_var_value == NULL) { + return true; + } + + // The values are joined with ';' in case we ever want to make this a + // generator parameter also (instead of env var), and generator parameter + // parsing already has meaning for ',' and ':'. + vector<string> file_paths = Split(env_var_value, ";", true); + + for (vector<string>::const_iterator i = file_paths.begin(); + i != file_paths.end(); ++i) { + const string& file_path = *i; + + ifstream stream(file_path.c_str(), ifstream::in); + if (!stream.good()) { + if (error != NULL) { + stringstream err_stream; + err_stream << endl << file_path << ":0:0: error: Unable to open"; + *error = err_stream.str(); + return false; + } + } + + string input_line; + while (stream.good()) { + getline(stream, input_line); + string trimmed_line(TrimString(input_line)); + if (trimmed_line.length() == 0) { + // Skip empty lines + continue; + } + if (trimmed_line[0] == '/' || trimmed_line[0] == '#') { + // Skip comments and potential preprocessor symbols + continue; + } + gClassWhitelist.insert(trimmed_line); + } + } + return true; +} + +bool FilterClass(const string& name) { + if (gClassWhitelist.count(name) > 0) { + // Whitelisted, don't filter. + return false; + } + + // If there was no list, default to everything in. + // If there was a list, default to everything out. + return gClassWhitelist.size() > 0; +} + +void TextFormatDecodeData::AddString(int32 key, + const string& input_for_decode, + const string& desired_output) { + for (vector<DataEntry>::const_iterator i = entries_.begin(); + i != entries_.end(); ++i) { + if (i->first == key) { + cerr << "error: duplicate key (" << key + << ") making TextFormat data, input: \"" << input_for_decode + << "\", desired: \"" << desired_output << "\"." << endl; + cerr.flush(); + abort(); + } + } + + const string& data = TextFormatDecodeData::DecodeDataForString( + input_for_decode, desired_output); + entries_.push_back(DataEntry(key, data)); +} + +string TextFormatDecodeData::Data() const { + 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 (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; + } + string Finish() { + Push(); + return decode_data_; + } + + private: + static const uint8 kAddUnderscore = 0x80; + + static const uint8 kOpAsIs = 0x00; + static const uint8 kOpFirstUpper = 0x40; + static const uint8 kOpFirstLower = 0x20; + static const uint8 kOpAllUpper = 0x60; + + static const int kMaxSegmentLen = 0x1f; + + void AddChar(const char desired) { + ++segment_len_; + is_all_upper_ &= IsUpper(desired); + } + + void Push() { + uint8 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 == ToUpper(input)) { + op_ = kOpFirstUpper; + } else if (desired == 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 op_; + int segment_len_; + + 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) || 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 == 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. +string DirectDecodeString(const string& str) { + string result; + result += (char)'\0'; // Marker for full string. + result += str; + result += (char)'\0'; // End of string. + return result; +} + +} // namespace + +// static +string TextFormatDecodeData::DecodeDataForString(const string& input_for_decode, + const string& desired_output) { + if ((input_for_decode.size() == 0) || (desired_output.size() == 0)) { + cerr << "error: got empty string for making TextFormat data, input: \"" + << input_for_decode << "\", desired: \"" << desired_output << "\"." + << endl; + cerr.flush(); + abort(); + } + if ((input_for_decode.find('\0') != string::npos) || + (desired_output.find('\0') != string::npos)) { + cerr << "error: got a null char in a string for making TextFormat data," + << " input: \"" << CEscape(input_for_decode) << "\", desired: \"" + << CEscape(desired_output) << "\"." << endl; + 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 objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h new file mode 100644 index 00000000..19317698 --- /dev/null +++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h @@ -0,0 +1,176 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (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_HELPERS_H__ +#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_HELPERS_H__ + +#include <string> +#include <vector> + +#include <google/protobuf/descriptor.h> +#include <google/protobuf/descriptor.pb.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +// Strips ".proto" or ".protodevel" from the end of a filename. +string StripProto(const string& filename); + +// Returns true if the name requires a ns_returns_not_retained attribute applied +// to it. +bool IsRetainedName(const string& name); + +// Returns true if the name starts with "init" and will need to have special +// handling under ARC. +bool IsInitName(const string& name); + +// Gets the name of the file we're going to generate (sans the .pb.h +// extension). This does not include the path to that file. +string FileName(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. +string FilePath(const FileDescriptor* file); + +// Checks the prefix for a given file and outputs any warnings/errors needed. +void ValidateObjCClassPrefix(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 the classes need +string FileClassName(const FileDescriptor* file); + +// These return the fully-qualified class name corresponding to the given +// descriptor. +string ClassName(const Descriptor* descriptor); +string EnumName(const EnumDescriptor* descriptor); + +// Returns the fully-qualified name of the enum value corresponding to the +// the descriptor. +string EnumValueName(const EnumValueDescriptor* descriptor); + +// Returns the name of the enum value corresponding to the descriptor. +string EnumValueShortName(const EnumValueDescriptor* descriptor); + +// Reverse what an enum does. +string UnCamelCaseEnumShortName(const string& name); + +// Returns the name to use for the extension (used as the method off the file's +// Root class). +string ExtensionMethodName(const FieldDescriptor* descriptor); + +// Returns the transformed field name. +string FieldName(const FieldDescriptor* field); +string FieldNameCapitalized(const FieldDescriptor* field); + +// Returns the transformed oneof name. +string OneofEnumName(const OneofDescriptor* descriptor); +string OneofName(const OneofDescriptor* descriptor); +string OneofNameCapitalized(const OneofDescriptor* descriptor); + +inline bool HasFieldPresence(const FileDescriptor* file) { + return file->syntax() != FileDescriptor::SYNTAX_PROTO3; +} + +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. +string UnCamelCaseFieldName(const 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 +}; + +string GetCapitalizedType(const FieldDescriptor* field); + +ObjectiveCType GetObjectiveCType(FieldDescriptor::Type field_type); + +inline ObjectiveCType GetObjectiveCType(const FieldDescriptor* field) { + return GetObjectiveCType(field->type()); +} + +bool IsPrimitiveType(const FieldDescriptor* field); +bool IsReferenceType(const FieldDescriptor* field); + +string GPBValueFieldName(const FieldDescriptor* field); +string DefaultValue(const FieldDescriptor* field); + +string BuildFlagsString(const vector<string>& strings); + +string BuildCommentsString(const SourceLocation& location); + +bool InitializeClassWhitelist(string* error); +bool FilterClass(const string& name); + +// Generate decode data needed for ObjC's GPBDecodeTextFormatName() to transform +// the input into the the expected output. +class LIBPROTOC_EXPORT TextFormatDecodeData { + public: + TextFormatDecodeData() {} + + void AddString(int32 key, const string& input_for_decode, + const string& desired_output); + size_t num_entries() const { return entries_.size(); } + string Data() const; + + static string DecodeDataForString(const string& input_for_decode, + const string& desired_output); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(TextFormatDecodeData); + + typedef std::pair<int32, string> DataEntry; + vector<DataEntry> entries_; +}; + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_HELPERS_H__ diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc b/src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc new file mode 100644 index 00000000..b091b77a --- /dev/null +++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc @@ -0,0 +1,249 @@ +// 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 <google/protobuf/compiler/objectivec/objectivec_helpers.h> +#include <google/protobuf/testing/googletest.h> +#include <gtest/gtest.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { +namespace { + +TEST(ObjCHelper, TextFormatDecodeData_DecodeDataForString_RawStrings) { + string input_for_decode("abcdefghIJ"); + string desired_output_for_decode; + string expected; + string result; + + // Different data, can't transform. + + desired_output_for_decode = "zbcdefghIJ"; + expected = string("\0zbcdefghIJ\0", 12); + result = TextFormatDecodeData::DecodeDataForString(input_for_decode, + desired_output_for_decode); + EXPECT_EQ(expected, result); + + desired_output_for_decode = "abcdezghIJ"; + expected = 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 = 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 = string("\0abcdefghIJz\0", 13); + result = TextFormatDecodeData::DecodeDataForString(input_for_decode, + desired_output_for_decode); + EXPECT_EQ(expected, result); +} + +TEST(ObjCHelper, TextFormatDecodeData_DecodeDataForString_ByteCodes) { + string input_for_decode("abcdefghIJ"); + string desired_output_for_decode; + string expected; + string result; + + desired_output_for_decode = "abcdefghIJ"; + expected = string("\x0A\x0", 2); + result = TextFormatDecodeData::DecodeDataForString(input_for_decode, + desired_output_for_decode); + EXPECT_EQ(expected, result); + + desired_output_for_decode = "_AbcdefghIJ"; + expected = 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 = 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 = 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. + + 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, + }; + 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, + }; + 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. + + 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 + +} // namespace +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc new file mode 100644 index 00000000..2987f3db --- /dev/null +++ b/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc @@ -0,0 +1,163 @@ +// 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 <google/protobuf/compiler/objectivec/objectivec_map_field.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/substitute.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) + : RepeatedFieldGenerator(descriptor) { + const FieldDescriptor* key_descriptor = + descriptor->message_type()->FindFieldByName("key"); + const FieldDescriptor* value_descriptor = + descriptor->message_type()->FindFieldByName("value"); + value_field_generator_.reset(FieldGenerator::Make(value_descriptor)); + + // 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<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") != + string::npos) { + field_flags.push_back("GPBFieldTextFormatNameCustom"); + } + // Pull over some info from the value's flags. + const string& value_field_flags = + value_field_generator_->variable("fieldflags"); + if (value_field_flags.find("GPBFieldHasDefaultValue") != string::npos) { + field_flags.push_back("GPBFieldHasDefaultValue"); + } + if (value_field_flags.find("GPBFieldHasEnumDescriptor") != string::npos) { + field_flags.push_back("GPBFieldHasEnumDescriptor"); + } + variables_["fieldflags"] = BuildFlagsString(field_flags); + + ObjectiveCType value_objc_type = GetObjectiveCType(value_descriptor); + if ((GetObjectiveCType(key_descriptor) == OBJECTIVECTYPE_STRING) && + ((value_objc_type == OBJECTIVECTYPE_STRING) || + (value_objc_type == OBJECTIVECTYPE_DATA) || + (value_objc_type == OBJECTIVECTYPE_MESSAGE))) { + variables_["array_storage_type"] = "NSMutableDictionary"; + } else { + string base_name = MapEntryTypeName(key_descriptor, true); + base_name += MapEntryTypeName(value_descriptor, false); + base_name += "Dictionary"; + variables_["array_storage_type"] = "GPB" + base_name; + } +} + +MapFieldGenerator::~MapFieldGenerator() {} + +void MapFieldGenerator::FinishInitialization(void) { + RepeatedFieldGenerator::FinishInitialization(); + // Use the array_comment suport in RepeatedFieldGenerator to output what the + // values in the map are. + const FieldDescriptor* value_descriptor = + descriptor_->message_type()->FindFieldByName("value"); + ObjectiveCType value_objc_type = GetObjectiveCType(value_descriptor); + if ((value_objc_type == OBJECTIVECTYPE_MESSAGE) || + (value_objc_type == OBJECTIVECTYPE_DATA) || + (value_objc_type == OBJECTIVECTYPE_STRING) || + (value_objc_type == OBJECTIVECTYPE_ENUM)) { + variables_["array_comment"] = + "// |" + variables_["name"] + "| values are |" + value_field_generator_->variable("storage_type") + "|\n"; + } else { + variables_["array_comment"] = ""; + } +} + +void MapFieldGenerator::GenerateFieldDescriptionTypeSpecific( + io::Printer* printer) const { + // Relay it to the value generator to provide enum validator, message + // class, etc. + value_field_generator_->GenerateFieldDescriptionTypeSpecific(printer); +} + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/objectivec/objectivec_map_field.h b/src/google/protobuf/compiler/objectivec/objectivec_map_field.h new file mode 100644 index 00000000..173541f2 --- /dev/null +++ b/src/google/protobuf/compiler/objectivec/objectivec_map_field.h @@ -0,0 +1,64 @@ +// 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 <google/protobuf/compiler/objectivec/objectivec_field.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +class MapFieldGenerator : public RepeatedFieldGenerator { + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); + + public: + virtual void FinishInitialization(void); + virtual void GenerateFieldDescriptionTypeSpecific(io::Printer* printer) const; + + protected: + explicit MapFieldGenerator(const FieldDescriptor* descriptor); + virtual ~MapFieldGenerator(); + + private: + scoped_ptr<FieldGenerator> value_field_generator_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapFieldGenerator); +}; + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MAP_FIELD_H__ diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message.cc b/src/google/protobuf/compiler/objectivec/objectivec_message.cc new file mode 100644 index 00000000..52e583bf --- /dev/null +++ b/src/google/protobuf/compiler/objectivec/objectivec_message.cc @@ -0,0 +1,654 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <algorithm> +#include <iostream> +#include <sstream> + +#include <google/protobuf/stubs/hash.h> +#include <google/protobuf/compiler/objectivec/objectivec_message.h> +#include <google/protobuf/compiler/objectivec/objectivec_enum.h> +#include <google/protobuf/compiler/objectivec/objectivec_extension.h> +#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> +#include <google/protobuf/stubs/stl_util.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/wire_format_lite_inl.h> +#include <google/protobuf/descriptor.pb.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +using internal::WireFormat; +using internal::WireFormatLite; + +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. Bools (1 byte) + // 2. Anything always 4 bytes - float, *32, enums + // 3. Anything that is always a pointer (they will be 8 bytes on 64 bit + // builds and 4 bytes on 32bit builds. + // 4. Anything always 8 bytes - double, *64 + // + // 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; + + // 1 byte. + case FieldDescriptor::TYPE_BOOL: + return 1; + } + + // 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); + } + 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); + } + sort(fields, fields + descriptor->field_count(), + FieldOrderingByStorageSize()); + return fields; +} +} // namespace + +MessageGenerator::MessageGenerator(const string& root_classname, + const Descriptor* descriptor) + : root_classname_(root_classname), + descriptor_(descriptor), + field_generators_(descriptor), + class_name_(ClassName(descriptor_)), + sub_content_filtered_(true) { + if (FilterClass(class_name_)) { + filter_reason_ = + string("Message |") + class_name_ + "| was not whitelisted."; + } + if (!IsFiltered()) { + // No need to generate extensions if this message is filtered + for (int i = 0; i < descriptor_->extension_count(); i++) { + extension_generators_.push_back( + new ExtensionGenerator(class_name_, descriptor_->extension(i))); + } + // No need to generate oneofs if this message is filtered. + for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { + OneofGenerator* generator = new OneofGenerator(descriptor_->oneof_decl(i)); + oneof_generators_.push_back(generator); + } + } + + // We may have enums of this message that are used even if the message + // itself is filtered. + for (int i = 0; i < descriptor_->enum_type_count(); i++) { + EnumGenerator* generator = new EnumGenerator(descriptor_->enum_type(i)); + // The enums are exposed via C functions, so they will dead strip if + // not used. + sub_content_filtered_ &= false; + enum_generators_.push_back(generator); + } + + // We may have nested messages that are used even if the message itself + // is filtered. + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + const Descriptor* nested_descriptor = descriptor_->nested_type(i); + MessageGenerator* generator = + new MessageGenerator(root_classname_, nested_descriptor); + // Don't check map entries for being filtered, as they don't directly + // generate anything in Objective C. In theory, they only should include + // references to other toplevel types, but we still make the generators + // to be safe. + if (!IsMapEntryMessage(nested_descriptor)) { + sub_content_filtered_ &= generator->IsFiltered(); + } + sub_content_filtered_ &= generator->IsSubContentFiltered(); + nested_message_generators_.push_back(generator); + } +} + +MessageGenerator::~MessageGenerator() { + STLDeleteContainerPointers(extension_generators_.begin(), + extension_generators_.end()); + STLDeleteContainerPointers(enum_generators_.begin(), enum_generators_.end()); + STLDeleteContainerPointers(nested_message_generators_.begin(), + nested_message_generators_.end()); + STLDeleteContainerPointers(oneof_generators_.begin(), + oneof_generators_.end()); +} + +void MessageGenerator::GenerateStaticVariablesInitialization( + io::Printer* printer, bool* out_generated) { + if (!IsFiltered()) { + // Skip extensions if we are filtered. + for (vector<ExtensionGenerator*>::iterator iter = + extension_generators_.begin(); + iter != extension_generators_.end(); ++iter) { + (*iter)->GenerateStaticVariablesInitialization(printer, out_generated, + false); + } + } + + // Generating sub messages is perfectly fine though. + for (vector<MessageGenerator*>::iterator iter = + nested_message_generators_.begin(); + iter != nested_message_generators_.end(); ++iter) { + (*iter)->GenerateStaticVariablesInitialization(printer, out_generated); + } +} + +void MessageGenerator::DetermineForwardDeclarations(set<string>* fwd_decls) { + if (!IsFiltered() && !IsMapEntryMessage(descriptor_)) { + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* fieldDescriptor = descriptor_->field(i); + // If it is a the field is repeated, the type will be and *Array, + // and we don't need any forward decl. + if (fieldDescriptor->is_repeated()) { + continue; + } + field_generators_.get(fieldDescriptor) + .DetermineForwardDeclarations(fwd_decls); + } + } + + for (vector<MessageGenerator*>::iterator iter = + nested_message_generators_.begin(); + iter != nested_message_generators_.end(); ++iter) { + (*iter)->DetermineForwardDeclarations(fwd_decls); + } +} + +void MessageGenerator::GenerateEnumHeader(io::Printer* printer) { + for (vector<EnumGenerator*>::iterator iter = enum_generators_.begin(); + iter != enum_generators_.end(); ++iter) { + (*iter)->GenerateHeader(printer); + } + + for (vector<MessageGenerator*>::iterator iter = + nested_message_generators_.begin(); + iter != nested_message_generators_.end(); ++iter) { + (*iter)->GenerateEnumHeader(printer); + } +} + +void MessageGenerator::GenerateExtensionRegistrationSource( + io::Printer* printer) { + if (!IsFiltered()) { + for (vector<ExtensionGenerator*>::iterator iter = + extension_generators_.begin(); + iter != extension_generators_.end(); ++iter) { + (*iter)->GenerateRegistrationSource(printer); + } + } + + for (vector<MessageGenerator*>::iterator iter = + nested_message_generators_.begin(); + iter != nested_message_generators_.end(); ++iter) { + (*iter)->GenerateExtensionRegistrationSource(printer); + } +} + +void MessageGenerator::GenerateMessageHeader(io::Printer* printer) { + // This a a map entry message, just recurse and do nothing directly. + if (IsMapEntryMessage(descriptor_)) { + for (vector<MessageGenerator*>::iterator iter = + nested_message_generators_.begin(); + iter != nested_message_generators_.end(); ++iter) { + (*iter)->GenerateMessageHeader(printer); + } + return; + } + + if (IsFiltered()) { + printer->Print("// $filter_reason$\n\n", + "filter_reason", filter_reason_); + } else { + printer->Print( + "#pragma mark - $classname$\n" + "\n", + "classname", class_name_); + + if (descriptor_->field_count()) { + // Even if there are fields, they could be filtered away, so always use + // a buffer to confirm we have something. + ostringstream fieldnumber_stringstream; + { + scoped_array<const FieldDescriptor*> sorted_fields( + SortFieldsByNumber(descriptor_)); + + io::OstreamOutputStream fieldnumber_outputstream( + &fieldnumber_stringstream); + io::Printer fieldnumber_printer(&fieldnumber_outputstream, '$'); + for (int i = 0; i < descriptor_->field_count(); i++) { + field_generators_.get(sorted_fields[i]) + .GenerateFieldNumberConstant(&fieldnumber_printer); + } + fieldnumber_stringstream.flush(); + } + const string& fieldnumber_str = fieldnumber_stringstream.str(); + if (fieldnumber_str.length()) { + printer->Print("typedef GPB_ENUM($classname$_FieldNumber) {\n", + "classname", class_name_); + printer->Indent(); + printer->Print(fieldnumber_str.c_str()); + printer->Outdent(); + printer->Print("};\n\n"); + } + } + + for (vector<OneofGenerator*>::iterator iter = oneof_generators_.begin(); + iter != oneof_generators_.end(); ++iter) { + (*iter)->GenerateCaseEnum(printer); + } + + string message_comments; + SourceLocation location; + if (descriptor_->GetSourceLocation(&location)) { + message_comments = BuildCommentsString(location); + } else { + message_comments = ""; + } + + printer->Print( + "$comments$@interface $classname$ : GPBMessage\n\n", + "classname", class_name_, + "comments", message_comments); + + vector<char> seen_oneofs(descriptor_->oneof_decl_count(), 0); + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + if (field->containing_oneof() != NULL) { + const int oneof_index = field->containing_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 (vector<OneofGenerator*>::iterator iter = oneof_generators_.begin(); + iter != oneof_generators_.end(); ++iter) { + (*iter)->GenerateClearFunctionDeclaration(printer); + } + printer->Print("\n"); + } + + if (descriptor_->extension_count() > 0) { + printer->Print("@interface $classname$ (DynamicMethods)\n\n", + "classname", class_name_); + for (vector<ExtensionGenerator*>::iterator iter = + extension_generators_.begin(); + iter != extension_generators_.end(); ++iter) { + (*iter)->GenerateMembersHeader(printer); + } + printer->Print("@end\n\n"); + } + } + + for (vector<MessageGenerator*>::iterator iter = + nested_message_generators_.begin(); + iter != nested_message_generators_.end(); ++iter) { + (*iter)->GenerateMessageHeader(printer); + } +} + +void MessageGenerator::GenerateSource(io::Printer* printer) { + if (!IsFiltered() && !IsMapEntryMessage(descriptor_)) { + printer->Print( + "#pragma mark - $classname$\n" + "\n", + "classname", class_name_); + + printer->Print("@implementation $classname$\n\n", + "classname", class_name_); + + for (vector<OneofGenerator*>::iterator iter = oneof_generators_.begin(); + iter != oneof_generators_.end(); ++iter) { + (*iter)->GeneratePropertyImplementation(printer); + } + + for (int i = 0; i < descriptor_->field_count(); i++) { + field_generators_.get(descriptor_->field(i)) + .GeneratePropertyImplementation(printer); + } + + scoped_array<const FieldDescriptor*> sorted_fields( + SortFieldsByNumber(descriptor_)); + scoped_array<const FieldDescriptor*> size_order_fields( + SortFieldsByStorageSize(descriptor_)); + + vector<const Descriptor::ExtensionRange*> sorted_extensions; + for (int i = 0; i < descriptor_->extension_range_count(); ++i) { + sorted_extensions.push_back(descriptor_->extension_range(i)); + } + + sort(sorted_extensions.begin(), sorted_extensions.end(), + ExtensionRangeOrdering()); + + size_t num_has_bits = descriptor_->field_count(); + size_t sizeof_has_storage = (num_has_bits + 31) / 32; + // Tell all the fields the oneof base. + for (vector<OneofGenerator*>::iterator iter = oneof_generators_.begin(); + iter != oneof_generators_.end(); ++iter) { + (*iter)->SetOneofIndexBase(sizeof_has_storage); + } + field_generators_.SetOneofIndexBase(sizeof_has_storage); + // Add an int32 for each oneof to store which is set. + sizeof_has_storage += descriptor_->oneof_decl_count(); + + printer->Print( + "\n" + "typedef struct $classname$_Storage {\n" + " uint32_t _has_storage_[$sizeof_has_storage$];\n", + "classname", class_name_, + "sizeof_has_storage", SimpleItoa(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 = NULL;\n" + " if (!descriptor) {\n"); + + bool has_oneofs = oneof_generators_.size(); + if (has_oneofs) { + printer->Print( + " static GPBMessageOneofDescription oneofs[] = {\n"); + printer->Indent(); + printer->Indent(); + printer->Indent(); + for (vector<OneofGenerator*>::iterator iter = oneof_generators_.begin(); + iter != oneof_generators_.end(); ++iter) { + (*iter)->GenerateDescription(printer); + } + printer->Outdent(); + printer->Outdent(); + printer->Outdent(); + printer->Print( + " };\n"); + } + + printer->Print( + " static GPBMessageFieldDescription fields[] = {\n"); + printer->Indent(); + printer->Indent(); + printer->Indent(); + TextFormatDecodeData text_format_decode_data; + for (int i = 0; i < descriptor_->field_count(); ++i) { + const FieldGenerator& field_generator = + field_generators_.get(sorted_fields[i]); + field_generator.GenerateFieldDescription(printer); + 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->Outdent(); + printer->Outdent(); + + bool has_enums = enum_generators_.size(); + if (has_enums) { + printer->Print( + " };\n" + " static GPBMessageEnumDescription enums[] = {\n"); + printer->Indent(); + printer->Indent(); + printer->Indent(); + for (vector<EnumGenerator*>::iterator iter = enum_generators_.begin(); + iter != enum_generators_.end(); ++iter) { + printer->Print("{ .enumDescriptorFunc = $name$_EnumDescriptor },\n", + "name", (*iter)->name()); + } + printer->Outdent(); + printer->Outdent(); + printer->Outdent(); + } + + bool has_extensions = sorted_extensions.size(); + if (has_extensions) { + printer->Print( + " };\n" + " static GPBExtensionRange ranges[] = {\n"); + printer->Indent(); + printer->Indent(); + printer->Indent(); + for (int i = 0; i < sorted_extensions.size(); i++) { + printer->Print("{ .start = $start$, .end = $end$ },\n", + "start", SimpleItoa(sorted_extensions[i]->start), + "end", SimpleItoa(sorted_extensions[i]->end)); + } + printer->Outdent(); + printer->Outdent(); + printer->Outdent(); + } + + map<string, string> vars; + vars["classname"] = class_name_; + vars["rootclassname"] = root_classname_; + vars["oneofs"] = has_oneofs ? "oneofs" : "NULL"; + vars["oneof_count"] = + has_oneofs ? "sizeof(oneofs) / sizeof(GPBMessageOneofDescription)" : "0"; + vars["enums"] = has_enums ? "enums" : "NULL"; + vars["enum_count"] = + has_enums ? "sizeof(enums) / sizeof(GPBMessageEnumDescription)" : "0"; + vars["ranges"] = has_extensions ? "ranges" : "NULL"; + vars["range_count"] = + has_extensions ? "sizeof(ranges) / sizeof(GPBExtensionRange)" : "0"; + vars["wireformat"] = + descriptor_->options().message_set_wire_format() ? "YES" : "NO"; + + printer->Print(" };\n"); + if (text_format_decode_data.num_entries() == 0) { + printer->Print( + vars, + " descriptor = [GPBDescriptor allocDescriptorForClass:[$classname$ class]\n" + " rootClass:[$rootclassname$ class]\n" + " file:$rootclassname$_FileDescriptor()\n" + " fields:fields\n" + " fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)\n" + " oneofs:$oneofs$\n" + " oneofCount:$oneof_count$\n" + " enums:$enums$\n" + " enumCount:$enum_count$\n" + " ranges:$ranges$\n" + " rangeCount:$range_count$\n" + " storageSize:sizeof($classname$_Storage)\n" + " wireFormat:$wireformat$];\n"); + } else { + vars["extraTextFormatInfo"] = CEscape(text_format_decode_data.Data()); + printer->Print( + vars, + "#if GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS\n" + " const char *extraTextFormatInfo = NULL;\n" + "#else\n" + " static const char *extraTextFormatInfo = \"$extraTextFormatInfo$\";\n" + "#endif // GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS\n" + " descriptor = [GPBDescriptor allocDescriptorForClass:[$classname$ class]\n" + " rootClass:[$rootclassname$ class]\n" + " file:$rootclassname$_FileDescriptor()\n" + " fields:fields\n" + " fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)\n" + " oneofs:$oneofs$\n" + " oneofCount:$oneof_count$\n" + " enums:$enums$\n" + " enumCount:$enum_count$\n" + " ranges:$ranges$\n" + " rangeCount:$range_count$\n" + " storageSize:sizeof($classname$_Storage)\n" + " wireFormat:$wireformat$\n" + " extraTextFormatInfo:extraTextFormatInfo];\n"); + } + printer->Print( + " }\n" + " return descriptor;\n" + "}\n\n" + "@end\n\n"); + + for (int i = 0; i < descriptor_->field_count(); i++) { + field_generators_.get(descriptor_->field(i)) + .GenerateCFunctionImplementations(printer); + } + + for (vector<OneofGenerator*>::iterator iter = oneof_generators_.begin(); + iter != oneof_generators_.end(); ++iter) { + (*iter)->GenerateClearFunctionImplementation(printer); + } + } + + for (vector<EnumGenerator*>::iterator iter = enum_generators_.begin(); + iter != enum_generators_.end(); ++iter) { + (*iter)->GenerateSource(printer); + } + + for (vector<MessageGenerator*>::iterator iter = + nested_message_generators_.begin(); + iter != nested_message_generators_.end(); ++iter) { + (*iter)->GenerateSource(printer); + } +} + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message.h b/src/google/protobuf/compiler/objectivec/objectivec_message.h new file mode 100644 index 00000000..8d03c0b8 --- /dev/null +++ b/src/google/protobuf/compiler/objectivec/objectivec_message.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. + +#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_H__ +#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_H__ + +#include <string> +#include <set> +#include <vector> +#include <google/protobuf/compiler/objectivec/objectivec_field.h> +#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> +#include <google/protobuf/compiler/objectivec/objectivec_oneof.h> +#include <google/protobuf/stubs/common.h> + +namespace google { +namespace protobuf { + +namespace io { +class Printer; // printer.h +} // namespace io + +namespace compiler { +namespace objectivec { + +class ExtensionGenerator; +class EnumGenerator; + +class MessageGenerator { + public: + MessageGenerator(const string& root_classname, const Descriptor* descriptor); + ~MessageGenerator(); + + void GenerateStaticVariablesInitialization(io::Printer* printer, + bool* out_generated); + void GenerateEnumHeader(io::Printer* printer); + void GenerateMessageHeader(io::Printer* printer); + void GenerateSource(io::Printer* printer); + void GenerateExtensionRegistrationSource(io::Printer* printer); + void DetermineForwardDeclarations(set<string>* fwd_decls); + + // This only speaks for this message, not sub message/enums. + bool IsFiltered() const { return filter_reason_.length() > 0; } + // This message being filtered doesn't effect this, instead it covers if + // there are any nested messages or enums. + bool IsSubContentFiltered() const { return sub_content_filtered_; } + + 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 string root_classname_; + const Descriptor* descriptor_; + FieldGeneratorMap field_generators_; + const string class_name_; + string filter_reason_; + bool sub_content_filtered_; + vector<ExtensionGenerator*> extension_generators_; + vector<EnumGenerator*> enum_generators_; + vector<MessageGenerator*> nested_message_generators_; + vector<OneofGenerator*> oneof_generators_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator); +}; +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_H__ diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc new file mode 100644 index 00000000..2e3bdfdb --- /dev/null +++ b/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc @@ -0,0 +1,96 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include <map> +#include <string> + +#include <google/protobuf/compiler/objectivec/objectivec_message_field.h> +#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +namespace { + +void SetMessageVariables(const FieldDescriptor* descriptor, + map<string, string>* variables) { + const string& message_type = ClassName(descriptor->message_type()); + (*variables)["type"] = message_type; + (*variables)["containing_class"] = ClassName(descriptor->containing_type()); + (*variables)["storage_type"] = message_type; + (*variables)["group_or_message"] = + (descriptor->type() == FieldDescriptor::TYPE_GROUP) ? "Group" : "Message"; + + (*variables)["typeSpecific_value"] = "GPBStringifySymbol(" + message_type + ")"; +} + +} // namespace + +MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor) + : ObjCObjFieldGenerator(descriptor) { + SetMessageVariables(descriptor, &variables_); +} + +MessageFieldGenerator::~MessageFieldGenerator() {} + +void MessageFieldGenerator::DetermineForwardDeclarations( + set<string>* fwd_decls) const { + // Class name is already in "storage_type". + fwd_decls->insert("@class " + variable("storage_type")); +} + +bool MessageFieldGenerator::WantsHasProperty(void) const { + if (descriptor_->containing_oneof() != NULL) { + // If in a oneof, it uses the oneofcase instead of a has bit. + return false; + } + // In both proto2 & proto3, message fields have a has* property to tell + // when it is a non default value. + return true; +} + +RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator( + const FieldDescriptor* descriptor) + : RepeatedFieldGenerator(descriptor) { + SetMessageVariables(descriptor, &variables_); + variables_["array_storage_type"] = "NSMutableArray"; +} + +RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {} + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message_field.h b/src/google/protobuf/compiler/objectivec/objectivec_message_field.h new file mode 100644 index 00000000..708ea566 --- /dev/null +++ b/src/google/protobuf/compiler/objectivec/objectivec_message_field.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_OBJECTIVEC_MESSAGE_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_FIELD_H__ + +#include <map> +#include <string> +#include <google/protobuf/compiler/objectivec/objectivec_field.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +class MessageFieldGenerator : public ObjCObjFieldGenerator { + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); + + protected: + explicit MessageFieldGenerator(const FieldDescriptor* descriptor); + virtual ~MessageFieldGenerator(); + virtual bool WantsHasProperty(void) const; + + public: + virtual void DetermineForwardDeclarations(set<string>* fwd_decls) const; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator); +}; + +class RepeatedMessageFieldGenerator : public RepeatedFieldGenerator { + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); + + protected: + explicit RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor); + virtual ~RepeatedMessageFieldGenerator(); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator); +}; + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_FIELD_H__ diff --git a/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc b/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc new file mode 100644 index 00000000..77664c68 --- /dev/null +++ b/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc @@ -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. + +#include <map> +#include <string> + +#include <google/protobuf/compiler/objectivec/objectivec_oneof.h> +#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/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"] = SimpleItoa(descriptor_->index()); + const Descriptor* msg_descriptor = descriptor_->containing_type(); + variables_["owning_message_class"] = ClassName(msg_descriptor); + + string comments; + SourceLocation location; + if (descriptor_->GetSourceLocation(&location)) { + comments = BuildCommentsString(location); + } 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"] = SimpleItoa(-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"); + string enum_name = variables_["enum_name"]; + for (int j = 0; j < descriptor_->field_count(); j++) { + const FieldDescriptor* field = descriptor_->field(j); + string field_name = FieldNameCapitalized(field); + printer->Print( + "$enum_name$_$field_name$ = $field_number$,\n", + "enum_name", enum_name, + "field_name", field_name, + "field_number", SimpleItoa(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_, + "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 = [message descriptor];\n" + " GPBOneofDescriptor *oneof = descriptor->oneofs_[$raw_index$];\n" + " GPBMaybeClearOneof(message, oneof, 0);\n" + "}\n"); +} + +void OneofGenerator::GenerateDescription(io::Printer* printer) { + printer->Print( + variables_, + "{\n" + " .name = \"$name$\",\n" + " .index = $index$,\n" + "},\n"); +} + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/objectivec/objectivec_oneof.h b/src/google/protobuf/compiler/objectivec/objectivec_oneof.h new file mode 100644 index 00000000..bcba82da --- /dev/null +++ b/src/google/protobuf/compiler/objectivec/objectivec_oneof.h @@ -0,0 +1,77 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ONEOF_H__ +#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ONEOF_H__ + +#include <string> +#include <set> +#include <vector> +#include <google/protobuf/descriptor.h> + +namespace google { +namespace protobuf { +namespace io { +class Printer; // printer.h +} +} + +namespace protobuf { +namespace compiler { +namespace objectivec { + +class OneofGenerator { + public: + explicit OneofGenerator(const OneofDescriptor* descriptor); + ~OneofGenerator(); + + 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); + void GenerateDescription(io::Printer* printer); + + private: + const OneofDescriptor* descriptor_; + map<string, string> variables_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OneofGenerator); +}; + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ONEOF_H__ diff --git a/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc new file mode 100644 index 00000000..c185b66d --- /dev/null +++ b/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc @@ -0,0 +1,171 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (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 <google/protobuf/compiler/objectivec/objectivec_primitive_field.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/wire_format_lite_inl.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/stubs/substitute.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; + } + + // 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: + return ""; // Want NSArray + } + + // 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, + map<string, string>* variables) { + std::string primitive_name = PrimitiveTypeName(descriptor); + (*variables)["type"] = primitive_name; + (*variables)["storage_type"] = primitive_name; +} + +} // namespace + +PrimitiveFieldGenerator::PrimitiveFieldGenerator( + const FieldDescriptor* descriptor) + : SingleFieldGenerator(descriptor) { + SetPrimitiveVariables(descriptor, &variables_); +} + +PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {} + +PrimitiveObjFieldGenerator::PrimitiveObjFieldGenerator( + const FieldDescriptor* descriptor) + : ObjCObjFieldGenerator(descriptor) { + SetPrimitiveVariables(descriptor, &variables_); + variables_["property_storage_attribute"] = "copy"; +} + +PrimitiveObjFieldGenerator::~PrimitiveObjFieldGenerator() {} + +RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator( + const FieldDescriptor* descriptor) + : RepeatedFieldGenerator(descriptor) { + SetPrimitiveVariables(descriptor, &variables_); + + string base_name = PrimitiveArrayTypeName(descriptor); + if (base_name.length()) { + variables_["array_storage_type"] = "GPB" + base_name + "Array"; + } else { + variables_["array_storage_type"] = "NSMutableArray"; + } +} + +RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {} + +void RepeatedPrimitiveFieldGenerator::FinishInitialization(void) { + RepeatedFieldGenerator::FinishInitialization(); + if (IsPrimitiveType(descriptor_)) { + // No comment needed for primitive types. + variables_["array_comment"] = ""; + } +} + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h b/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h new file mode 100644 index 00000000..9bb79343 --- /dev/null +++ b/src/google/protobuf/compiler/objectivec/objectivec_primitive_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_OBJECTIVEC_PRIMITIVE_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_PRIMITIVE_FIELD_H__ + +#include <map> +#include <string> +#include <google/protobuf/compiler/objectivec/objectivec_field.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +class PrimitiveFieldGenerator : public SingleFieldGenerator { + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); + + protected: + explicit PrimitiveFieldGenerator(const FieldDescriptor* descriptor); + virtual ~PrimitiveFieldGenerator(); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator); +}; + +class PrimitiveObjFieldGenerator : public ObjCObjFieldGenerator { + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); + + protected: + explicit PrimitiveObjFieldGenerator(const FieldDescriptor* descriptor); + virtual ~PrimitiveObjFieldGenerator(); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveObjFieldGenerator); +}; + +class RepeatedPrimitiveFieldGenerator : public RepeatedFieldGenerator { + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); + + protected: + explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor); + virtual ~RepeatedPrimitiveFieldGenerator(); + virtual void FinishInitialization(void); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPrimitiveFieldGenerator); +}; + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_PRIMITIVE_FIELD_H__ diff --git a/src/google/protobuf/compiler/parser.cc b/src/google/protobuf/compiler/parser.cc index c50cdf54..a2eeee2d 100644 --- a/src/google/protobuf/compiler/parser.cc +++ b/src/google/protobuf/compiler/parser.cc @@ -686,6 +686,8 @@ bool Parser::ParseMessageStatement(DescriptorProto* message, 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); @@ -733,6 +735,13 @@ bool Parser::ParseMessageField(FieldDescriptorProto* field, FieldDescriptorProto::Label label; if (ParseLabel(&label, containing_file)) { field->set_label(label); + if (label == FieldDescriptorProto::LABEL_OPTIONAL && + syntax_identifier_ == "proto3") { + AddError( + "Explicit 'optional' labels are disallowed in the Proto3 syntax. " + "To define 'optional' fields in Proto3, simply remove the " + "'optional' label, as fields are 'optional' by default."); + } } } @@ -1353,6 +1362,77 @@ bool Parser::ParseExtensions(DescriptorProto* message, return true; } +// This is similar to extension range parsing, except that "max" is not +// supported, and accepts field name literals. +bool Parser::ParseReserved(DescriptorProto* message, + const LocationRecorder& message_location) { + // Parse the declaration. + DO(Consume("reserved")); + if (LookingAtType(io::Tokenizer::TYPE_STRING)) { + LocationRecorder location(message_location, + DescriptorProto::kReservedNameFieldNumber); + return ParseReservedNames(message, location); + } else { + LocationRecorder location(message_location, + DescriptorProto::kReservedRangeFieldNumber); + 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); + 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::ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions, RepeatedPtrField<DescriptorProto>* messages, const LocationRecorder& parent_location, diff --git a/src/google/protobuf/compiler/parser.h b/src/google/protobuf/compiler/parser.h index 7cb1678a..16012e96 100644 --- a/src/google/protobuf/compiler/parser.h +++ b/src/google/protobuf/compiler/parser.h @@ -364,6 +364,14 @@ class LIBPROTOBUF_EXPORT Parser { const LocationRecorder& extensions_location, const FileDescriptorProto* containing_file); + // Parse an "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); + // Parse an "extend" declaration. (See also comments for // ParseMessageField().) bool ParseExtend(RepeatedPtrField<FieldDescriptorProto>* extensions, diff --git a/src/google/protobuf/compiler/parser_unittest.cc b/src/google/protobuf/compiler/parser_unittest.cc index 1684bebe..ddf34bfa 100644 --- a/src/google/protobuf/compiler/parser_unittest.cc +++ b/src/google/protobuf/compiler/parser_unittest.cc @@ -620,6 +620,36 @@ TEST_F(ParseMessageTest, NestedEnum) { "}"); } +TEST_F(ParseMessageTest, ReservedRange) { + ExpectParsesTo( + "message TestMessage {\n" + " required int32 foo = 1;\n" + " reserved 2, 15, 9 to 11, 3;\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 }" + "}"); +} + +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" @@ -715,19 +745,17 @@ TEST_F(ParseMessageTest, MultipleExtensionsOneExtendee) { " type_name:\"TestMessage\" extendee: \"Extendee1\" }"); } -TEST_F(ParseMessageTest, OptionalOptionalLabelProto3) { +TEST_F(ParseMessageTest, OptionalLabelProto3) { ExpectParsesTo( "syntax = \"proto3\";\n" "message TestMessage {\n" " int32 foo = 1;\n" - " optional int32 bar = 2;\n" "}\n", "syntax: \"proto3\" " "message_type {" " name: \"TestMessage\"" - " field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 }" - " field { name:\"bar\" label:LABEL_OPTIONAL type:TYPE_INT32 number:2 } }"); + " field { name:\"foo\" label:LABEL_OPTIONAL type:TYPE_INT32 number:1 } }"); } // =================================================================== @@ -1230,6 +1258,18 @@ TEST_F(ParseErrorTest, EofInAggregateValue) { "1:0: Unexpected end of stream while parsing aggregate value.\n"); } +TEST_F(ParseErrorTest, ExplicitOptionalLabelProto3) { + ExpectHasErrors( + "syntax = 'proto3';\n" + "message TestMessage {\n" + " optional int32 foo = 1;\n" + "}\n", + "2:11: Explicit 'optional' labels are disallowed in the Proto3 syntax. " + "To define 'optional' fields in Proto3, simply remove the 'optional' " + "label, as fields are 'optional' by default.\n"); +} + + // ------------------------------------------------------------------- // Enum errors @@ -1248,6 +1288,33 @@ TEST_F(ParseErrorTest, EnumValueMissingNumber) { } // ------------------------------------------------------------------- +// Reserved field number errors + +TEST_F(ParseErrorTest, ReservedMaxNotAllowed) { + ExpectHasErrors( + "message Foo {\n" + " reserved 10 to max;\n" + "}\n", + "1:17: Expected integer.\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"); +} + +// ------------------------------------------------------------------- // Service errors TEST_F(ParseErrorTest, EofInService) { diff --git a/src/google/protobuf/compiler/plugin.cc b/src/google/protobuf/compiler/plugin.cc index ad501acf..cdcaffde 100644 --- a/src/google/protobuf/compiler/plugin.cc +++ b/src/google/protobuf/compiler/plugin.cc @@ -134,20 +134,34 @@ int PluginMain(int argc, char* argv[], const CodeGenerator* generator) { CodeGeneratorResponse response; GeneratorResponseContext context(&response, parsed_files); - for (int i = 0; i < parsed_files.size(); i++) { - const FileDescriptor* file = parsed_files[i]; - + if (generator->HasGenerateAll()) { string error; - bool succeeded = generator->Generate( - file, request.parameter(), &context, &error); + bool succeeded = generator->GenerateAll( + parsed_files, request.parameter(), &context, &error); if (!succeeded && error.empty()) { error = "Code generator returned false but provided no error " "description."; } if (!error.empty()) { - response.set_error(file->name() + ": " + error); - break; + response.set_error(error); + } + } else { + for (int i = 0; i < parsed_files.size(); i++) { + const FileDescriptor* file = parsed_files[i]; + + string error; + bool succeeded = generator->Generate( + file, request.parameter(), &context, &error); + + if (!succeeded && error.empty()) { + error = "Code generator returned false but provided no error " + "description."; + } + if (!error.empty()) { + response.set_error(file->name() + ": " + error); + break; + } } } diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc index fed1726a..344ed450 100644 --- a/src/google/protobuf/compiler/plugin.pb.cc +++ b/src/google/protobuf/compiler/plugin.pb.cc @@ -179,7 +179,7 @@ const int CodeGeneratorRequest::kProtoFileFieldNumber; #endif // !_MSC_VER CodeGeneratorRequest::CodeGeneratorRequest() - : ::google::protobuf::Message() , _internal_metadata_(NULL) { + : ::google::protobuf::Message(), _internal_metadata_(NULL) { SharedCtor(); // @@protoc_insertion_point(constructor:google.protobuf.compiler.CodeGeneratorRequest) } @@ -300,12 +300,15 @@ bool CodeGeneratorRequest::MergePartialFromCodedStream( case 15: { if (tag == 122) { parse_proto_file: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + DO_(input->IncrementRecursionDepth()); + parse_loop_proto_file: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( input, add_proto_file())); } else { goto handle_unusual; } - if (input->ExpectTag(122)) goto parse_proto_file; + if (input->ExpectTag(122)) goto parse_loop_proto_file; + input->UnsafeDecrementRecursionDepth(); if (input->ExpectAtEnd()) goto success; break; } @@ -445,9 +448,9 @@ int CodeGeneratorRequest::ByteSize() const { void CodeGeneratorRequest::MergeFrom(const ::google::protobuf::Message& from) { if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - const CodeGeneratorRequest* source = - ::google::protobuf::internal::dynamic_cast_if_available<const CodeGeneratorRequest*>( - &from); + const CodeGeneratorRequest* source = + ::google::protobuf::internal::DynamicCastToGenerated<const CodeGeneratorRequest>( + &from); if (source == NULL) { ::google::protobuf::internal::ReflectionOps::Merge(from, this); } else { @@ -513,10 +516,10 @@ void CodeGeneratorRequest::InternalSwap(CodeGeneratorRequest* other) { // CodeGeneratorRequest // repeated string file_to_generate = 1; - int CodeGeneratorRequest::file_to_generate_size() const { +int CodeGeneratorRequest::file_to_generate_size() const { return file_to_generate_.size(); } - void CodeGeneratorRequest::clear_file_to_generate() { +void CodeGeneratorRequest::clear_file_to_generate() { file_to_generate_.Clear(); } const ::std::string& CodeGeneratorRequest::file_to_generate(int index) const { @@ -567,16 +570,16 @@ CodeGeneratorRequest::mutable_file_to_generate() { } // optional string parameter = 2; - bool CodeGeneratorRequest::has_parameter() const { +bool CodeGeneratorRequest::has_parameter() const { return (_has_bits_[0] & 0x00000002u) != 0; } - void CodeGeneratorRequest::set_has_parameter() { +void CodeGeneratorRequest::set_has_parameter() { _has_bits_[0] |= 0x00000002u; } - void CodeGeneratorRequest::clear_has_parameter() { +void CodeGeneratorRequest::clear_has_parameter() { _has_bits_[0] &= ~0x00000002u; } - void CodeGeneratorRequest::clear_parameter() { +void CodeGeneratorRequest::clear_parameter() { parameter_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); clear_has_parameter(); } @@ -620,10 +623,10 @@ CodeGeneratorRequest::mutable_file_to_generate() { } // repeated .google.protobuf.FileDescriptorProto proto_file = 15; - int CodeGeneratorRequest::proto_file_size() const { +int CodeGeneratorRequest::proto_file_size() const { return proto_file_.size(); } - void CodeGeneratorRequest::clear_proto_file() { +void CodeGeneratorRequest::clear_proto_file() { proto_file_.Clear(); } const ::google::protobuf::FileDescriptorProto& CodeGeneratorRequest::proto_file(int index) const { @@ -660,7 +663,7 @@ const int CodeGeneratorResponse_File::kContentFieldNumber; #endif // !_MSC_VER CodeGeneratorResponse_File::CodeGeneratorResponse_File() - : ::google::protobuf::Message() , _internal_metadata_(NULL) { + : ::google::protobuf::Message(), _internal_metadata_(NULL) { SharedCtor(); // @@protoc_insertion_point(constructor:google.protobuf.compiler.CodeGeneratorResponse.File) } @@ -724,7 +727,7 @@ CodeGeneratorResponse_File* CodeGeneratorResponse_File::New(::google::protobuf:: } void CodeGeneratorResponse_File::Clear() { - if (_has_bits_[0 / 32] & 7) { + if (_has_bits_[0 / 32] & 7u) { if (has_name()) { name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); } @@ -946,9 +949,9 @@ int CodeGeneratorResponse_File::ByteSize() const { void CodeGeneratorResponse_File::MergeFrom(const ::google::protobuf::Message& from) { if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - const CodeGeneratorResponse_File* source = - ::google::protobuf::internal::dynamic_cast_if_available<const CodeGeneratorResponse_File*>( - &from); + const CodeGeneratorResponse_File* source = + ::google::protobuf::internal::DynamicCastToGenerated<const CodeGeneratorResponse_File>( + &from); if (source == NULL) { ::google::protobuf::internal::ReflectionOps::Merge(from, this); } else { @@ -1024,7 +1027,7 @@ const int CodeGeneratorResponse::kFileFieldNumber; #endif // !_MSC_VER CodeGeneratorResponse::CodeGeneratorResponse() - : ::google::protobuf::Message() , _internal_metadata_(NULL) { + : ::google::protobuf::Message(), _internal_metadata_(NULL) { SharedCtor(); // @@protoc_insertion_point(constructor:google.protobuf.compiler.CodeGeneratorResponse) } @@ -1124,12 +1127,15 @@ bool CodeGeneratorResponse::MergePartialFromCodedStream( case 15: { if (tag == 122) { parse_file: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + DO_(input->IncrementRecursionDepth()); + parse_loop_file: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( input, add_file())); } else { goto handle_unusual; } - if (input->ExpectTag(122)) goto parse_file; + if (input->ExpectTag(122)) goto parse_loop_file; + input->UnsafeDecrementRecursionDepth(); if (input->ExpectAtEnd()) goto success; break; } @@ -1242,9 +1248,9 @@ int CodeGeneratorResponse::ByteSize() const { void CodeGeneratorResponse::MergeFrom(const ::google::protobuf::Message& from) { if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - const CodeGeneratorResponse* source = - ::google::protobuf::internal::dynamic_cast_if_available<const CodeGeneratorResponse*>( - &from); + const CodeGeneratorResponse* source = + ::google::protobuf::internal::DynamicCastToGenerated<const CodeGeneratorResponse>( + &from); if (source == NULL) { ::google::protobuf::internal::ReflectionOps::Merge(from, this); } else { @@ -1307,16 +1313,16 @@ void CodeGeneratorResponse::InternalSwap(CodeGeneratorResponse* other) { // CodeGeneratorResponse_File // optional string name = 1; - bool CodeGeneratorResponse_File::has_name() const { +bool CodeGeneratorResponse_File::has_name() const { return (_has_bits_[0] & 0x00000001u) != 0; } - void CodeGeneratorResponse_File::set_has_name() { +void CodeGeneratorResponse_File::set_has_name() { _has_bits_[0] |= 0x00000001u; } - void CodeGeneratorResponse_File::clear_has_name() { +void CodeGeneratorResponse_File::clear_has_name() { _has_bits_[0] &= ~0x00000001u; } - void CodeGeneratorResponse_File::clear_name() { +void CodeGeneratorResponse_File::clear_name() { name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); clear_has_name(); } @@ -1360,16 +1366,16 @@ void CodeGeneratorResponse::InternalSwap(CodeGeneratorResponse* other) { } // optional string insertion_point = 2; - bool CodeGeneratorResponse_File::has_insertion_point() const { +bool CodeGeneratorResponse_File::has_insertion_point() const { return (_has_bits_[0] & 0x00000002u) != 0; } - void CodeGeneratorResponse_File::set_has_insertion_point() { +void CodeGeneratorResponse_File::set_has_insertion_point() { _has_bits_[0] |= 0x00000002u; } - void CodeGeneratorResponse_File::clear_has_insertion_point() { +void CodeGeneratorResponse_File::clear_has_insertion_point() { _has_bits_[0] &= ~0x00000002u; } - void CodeGeneratorResponse_File::clear_insertion_point() { +void CodeGeneratorResponse_File::clear_insertion_point() { insertion_point_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); clear_has_insertion_point(); } @@ -1413,16 +1419,16 @@ void CodeGeneratorResponse::InternalSwap(CodeGeneratorResponse* other) { } // optional string content = 15; - bool CodeGeneratorResponse_File::has_content() const { +bool CodeGeneratorResponse_File::has_content() const { return (_has_bits_[0] & 0x00000004u) != 0; } - void CodeGeneratorResponse_File::set_has_content() { +void CodeGeneratorResponse_File::set_has_content() { _has_bits_[0] |= 0x00000004u; } - void CodeGeneratorResponse_File::clear_has_content() { +void CodeGeneratorResponse_File::clear_has_content() { _has_bits_[0] &= ~0x00000004u; } - void CodeGeneratorResponse_File::clear_content() { +void CodeGeneratorResponse_File::clear_content() { content_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); clear_has_content(); } @@ -1470,16 +1476,16 @@ void CodeGeneratorResponse::InternalSwap(CodeGeneratorResponse* other) { // CodeGeneratorResponse // optional string error = 1; - bool CodeGeneratorResponse::has_error() const { +bool CodeGeneratorResponse::has_error() const { return (_has_bits_[0] & 0x00000001u) != 0; } - void CodeGeneratorResponse::set_has_error() { +void CodeGeneratorResponse::set_has_error() { _has_bits_[0] |= 0x00000001u; } - void CodeGeneratorResponse::clear_has_error() { +void CodeGeneratorResponse::clear_has_error() { _has_bits_[0] &= ~0x00000001u; } - void CodeGeneratorResponse::clear_error() { +void CodeGeneratorResponse::clear_error() { error_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); clear_has_error(); } @@ -1523,10 +1529,10 @@ void CodeGeneratorResponse::InternalSwap(CodeGeneratorResponse* other) { } // repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15; - int CodeGeneratorResponse::file_size() const { +int CodeGeneratorResponse::file_size() const { return file_.size(); } - void CodeGeneratorResponse::clear_file() { +void CodeGeneratorResponse::clear_file() { file_.Clear(); } const ::google::protobuf::compiler::CodeGeneratorResponse_File& CodeGeneratorResponse::file(int index) const { diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h index ea48b8b5..6fcaea2e 100644 --- a/src/google/protobuf/compiler/plugin.pb.h +++ b/src/google/protobuf/compiler/plugin.pb.h @@ -796,6 +796,10 @@ CodeGeneratorResponse::mutable_file() { } #endif // !PROTOBUF_INLINE_NOT_IN_HEADERS +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + // @@protoc_insertion_point(namespace_scope) diff --git a/src/google/protobuf/compiler/ruby/ruby_generated_code.proto b/src/google/protobuf/compiler/ruby/ruby_generated_code.proto new file mode 100644 index 00000000..42d82a6b --- /dev/null +++ b/src/google/protobuf/compiler/ruby/ruby_generated_code.proto @@ -0,0 +1,67 @@ +syntax = "proto3"; + +package A.B.C; + +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; + + 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/src/google/protobuf/compiler/ruby/ruby_generated_code.rb b/src/google/protobuf/compiler/ruby/ruby_generated_code.rb new file mode 100644 index 00000000..100d6fa7 --- /dev/null +++ b/src/google/protobuf/compiler/ruby/ruby_generated_code.rb @@ -0,0 +1,74 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: ruby_generated_code.proto + +require 'google/protobuf' + +Google::Protobuf::DescriptorPool.generated_pool.build 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, :string, 9 + optional :optional_enum, :enum, 10, "A.B.C.TestEnum" + optional :optional_msg, :message, 11, "A.B.C.TestMessage" + 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, :string, 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, :string, 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 + +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/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc b/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc index e35ca695..6c203ab6 100644 --- a/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc +++ b/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc @@ -45,10 +45,10 @@ namespace compiler { namespace ruby { namespace { -string FindRubyTestDir() { +string FindRubyTestDir(const string& file) { // Inspired by TestSourceDir() in src/google/protobuf/testing/googletest.cc. string prefix = "."; - while (!File::Exists(prefix + "/ruby/tests")) { + while (!File::Exists(prefix + "/src/google/protobuf/compiler/ruby" + file)) { if (!File::Exists(prefix)) { GOOGLE_LOG(FATAL) << "Could not find Ruby test directory. Please run tests from " @@ -56,7 +56,7 @@ string FindRubyTestDir() { } prefix += "/.."; } - return prefix + "/ruby/tests"; + return prefix + "/src/google/protobuf/compiler/ruby"; } // This test is a simple golden-file test over the output of the Ruby code @@ -67,7 +67,7 @@ string FindRubyTestDir() { // extensions to the point where we can do this test in a more automated way. TEST(RubyGeneratorTest, GeneratorTest) { - string ruby_tests = FindRubyTestDir(); + string ruby_tests = FindRubyTestDir("/ruby_generated_code.proto"); google::protobuf::compiler::CommandLineInterface cli; cli.SetInputsAreProtoPathRelative(true); @@ -78,11 +78,11 @@ TEST(RubyGeneratorTest, GeneratorTest) { // Copy generated_code.proto to the temporary test directory. string test_input; GOOGLE_CHECK_OK(File::GetContents( - ruby_tests + "/generated_code.proto", + ruby_tests + "/ruby_generated_code.proto", &test_input, true)); GOOGLE_CHECK_OK(File::SetContents( - TestTempDir() + "/generated_code.proto", + TestTempDir() + "/ruby_generated_code.proto", test_input, true)); @@ -93,7 +93,7 @@ TEST(RubyGeneratorTest, GeneratorTest) { "protoc", ruby_out.c_str(), proto_path.c_str(), - "generated_code.proto", + "ruby_generated_code.proto", }; EXPECT_EQ(0, cli.Run(4, argv)); @@ -101,12 +101,12 @@ TEST(RubyGeneratorTest, GeneratorTest) { // Load the generated output and compare to the expected result. string output; GOOGLE_CHECK_OK(File::GetContents( - TestTempDir() + "/generated_code.rb", + TestTempDir() + "/ruby_generated_code.rb", &output, true)); string expected_output; GOOGLE_CHECK_OK(File::GetContents( - ruby_tests + "/generated_code.rb", + ruby_tests + "/ruby_generated_code.rb", &expected_output, true)); EXPECT_EQ(expected_output, output); diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index bfdacd95..2855c377 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -1518,6 +1518,18 @@ Descriptor::FindExtensionRangeContainingNumber(int number) const { return NULL; } +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 NULL; +} + // ------------------------------------------------------------------- bool DescriptorPool::TryFindFileInFallbackDatabase(const string& name) const { @@ -1741,6 +1753,14 @@ void Descriptor::CopyTo(DescriptorProto* proto) const { 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()); @@ -2186,6 +2206,29 @@ void Descriptor::DebugString(int depth, string *contents, 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 { + 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); } @@ -2278,8 +2321,12 @@ void FieldDescriptor::DebugString(int depth, } if (type() == TYPE_GROUP) { - message_type()->DebugString(depth, contents, debug_string_options, - /* include_opening_clause */ false); + 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"); } @@ -2308,12 +2355,16 @@ void OneofDescriptor::DebugString(int depth, string* contents, comment_printer(this, prefix, debug_string_options); comment_printer.AddPreComment(contents); strings::SubstituteAndAppend( - contents, "$0 oneof $1 {\n", prefix, name()); - for (int i = 0; i < field_count(); i++) { - field(i)->DebugString(depth, FieldDescriptor::OMIT_LABEL, contents, - debug_string_options); + contents, "$0 oneof $1 {", prefix, name()); + if (debug_string_options.elide_oneof_body) { + contents->append(" ... }\n"); + } else { + for (int i = 0; i < field_count(); i++) { + field(i)->DebugString(depth, FieldDescriptor::OMIT_LABEL, contents, + debug_string_options); + } + strings::SubstituteAndAppend(contents, "$0}\n", prefix); } - strings::SubstituteAndAppend(contents, "$0}\n", prefix); comment_printer.AddPostComment(contents); } @@ -2491,7 +2542,12 @@ bool FileDescriptor::GetSourceLocation(SourceLocation* out_location) const { } bool FieldDescriptor::is_packed() const { - return is_packable() && (options_ != NULL) && options_->packed(); + if (!is_packable()) return false; + if (file_->syntax() == FileDescriptor::SYNTAX_PROTO2) { + return (options_ != NULL) && options_->packed(); + } else { + return options_ == NULL || !options_->has_packed() || options_->packed(); + } } bool Descriptor::GetSourceLocation(SourceLocation* out_location) const { @@ -2604,7 +2660,7 @@ void MethodDescriptor::GetLocationPath(vector<int>* output) const { namespace { // Represents an options message to interpret. Extension names in the option -// name are respolved relative to name_scope. element_name and orig_opt are +// 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. @@ -2830,6 +2886,9 @@ class DescriptorBuilder { 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 BuildOneof(const OneofDescriptorProto& proto, Descriptor* parent, OneofDescriptor* result); @@ -3920,6 +3979,17 @@ void DescriptorBuilder::BuildMessage(const DescriptorProto& proto, 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 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. if (!proto.has_options()) { @@ -3931,7 +4001,34 @@ void DescriptorBuilder::BuildMessage(const DescriptorProto& proto, AddSymbol(result->full_name(), parent, result->name(), proto, Symbol(result)); - // Check that no fields have numbers in extension ranges. + 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<string> reserved_name_set; + for (int i = 0; i < proto.reserved_name_size(); i++) { + const 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++) { @@ -3945,11 +4042,39 @@ void DescriptorBuilder::BuildMessage(const DescriptorProto& proto, 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. + // Check that extension ranges don't overlap and don't include + // reserved field numbers. 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(j), + 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) { @@ -4262,6 +4387,19 @@ void DescriptorBuilder::BuildExtensionRange( } } +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::BuildOneof(const OneofDescriptorProto& proto, Descriptor* parent, OneofDescriptor* result) { @@ -4503,6 +4641,23 @@ void DescriptorBuilder::CrossLinkMessage( for (int i = 0; i < message->field_count(); i++) { const OneofDescriptor* oneof_decl = message->field(i)->containing_oneof(); if (oneof_decl != NULL) { + // 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) { + AddWarning( + message->full_name() + "." + message->field(i - 1)->name(), + proto.field(i - 1), DescriptorPool::ErrorCollector::OTHER, + 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. ++message->oneof_decls_[oneof_decl->index()].field_count_; @@ -4933,6 +5088,12 @@ void DescriptorBuilder::ValidateProto3Field( field->containing_type()->full_name() + "\" which is a proto3 message type."); } + bool allow_groups = false; + if (field->type() == FieldDescriptor::TYPE_GROUP && !allow_groups) { + AddError(field->full_name(), proto, + DescriptorPool::ErrorCollector::TYPE, + "Groups are not supported in proto3 syntax."); + } } void DescriptorBuilder::ValidateProto3Enum( diff --git a/src/google/protobuf/descriptor.h b/src/google/protobuf/descriptor.h index 0e264f54..ca87d634 100644 --- a/src/google/protobuf/descriptor.h +++ b/src/google/protobuf/descriptor.h @@ -59,6 +59,10 @@ #include <vector> #include <google/protobuf/stubs/common.h> +// TYPE_BOOL is defined in the MacOS's ConditionalMacros.h. +#ifdef TYPE_BOOL +#undef TYPE_BOOL +#endif // TYPE_BOOL namespace google { namespace protobuf { @@ -131,10 +135,14 @@ struct DebugStringOptions { // 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) - {} + : include_comments(false), + elide_group_body(false), + elide_oneof_body(false) {} }; // Describes a type of protocol message, or a particular group within a @@ -294,6 +302,36 @@ class LIBPROTOBUF_EXPORT Descriptor { // this message type's scope. const FieldDescriptor* FindExtensionByCamelcaseName(const string& 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 NULL 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 string& reserved_name(int index) const; + + // Returns true if the field name is reserved. + bool IsReservedName(const string& name) const; + // Source Location --------------------------------------------------- // Updates |*out_location| to the source location of the complete @@ -339,6 +377,10 @@ class LIBPROTOBUF_EXPORT Descriptor { ExtensionRange* extension_ranges_; int extension_count_; FieldDescriptor* extensions_; + int reserved_range_count_; + ReservedRange* reserved_ranges_; + int reserved_name_count_; + const string** reserved_names_; // 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. @@ -1563,6 +1605,12 @@ 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) @@ -1663,6 +1711,25 @@ inline bool Descriptor::IsExtensionNumber(int number) const { return FindExtensionRangeContainingNumber(number) != NULL; } +inline bool Descriptor::IsReservedNumber(int number) const { + return FindReservedRangeContainingNumber(number) != NULL; +} + +inline bool Descriptor::IsReservedName(const string& name) const { + for (int i = 0; i < reserved_name_count(); i++) { + if (name == 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 string& Descriptor::reserved_name(int index) const { + return *reserved_names_[index]; +} + inline bool FieldDescriptor::is_required() const { return label() == LABEL_REQUIRED; } diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc index 9556206c..755c2617 100644 --- a/src/google/protobuf/descriptor.pb.cc +++ b/src/google/protobuf/descriptor.pb.cc @@ -33,6 +33,9 @@ const ::google::protobuf::internal::GeneratedMessageReflection* const ::google::protobuf::Descriptor* DescriptorProto_ExtensionRange_descriptor_ = NULL; const ::google::protobuf::internal::GeneratedMessageReflection* DescriptorProto_ExtensionRange_reflection_ = NULL; +const ::google::protobuf::Descriptor* DescriptorProto_ReservedRange_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + DescriptorProto_ReservedRange_reflection_ = NULL; const ::google::protobuf::Descriptor* FieldDescriptorProto_descriptor_ = NULL; const ::google::protobuf::internal::GeneratedMessageReflection* FieldDescriptorProto_reflection_ = NULL; @@ -64,6 +67,7 @@ const ::google::protobuf::Descriptor* FieldOptions_descriptor_ = NULL; const ::google::protobuf::internal::GeneratedMessageReflection* FieldOptions_reflection_ = NULL; const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* FieldOptions_JSType_descriptor_ = NULL; const ::google::protobuf::Descriptor* EnumOptions_descriptor_ = NULL; const ::google::protobuf::internal::GeneratedMessageReflection* EnumOptions_reflection_ = NULL; @@ -140,7 +144,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, _internal_metadata_), -1); DescriptorProto_descriptor_ = file->message_type(2); - static const int DescriptorProto_offsets_[8] = { + static const int DescriptorProto_offsets_[10] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, field_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, extension_), @@ -149,6 +153,8 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, extension_range_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, oneof_decl_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, options_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, reserved_range_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, reserved_name_), }; DescriptorProto_reflection_ = ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( @@ -177,6 +183,22 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() { sizeof(DescriptorProto_ExtensionRange), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, _internal_metadata_), -1); + DescriptorProto_ReservedRange_descriptor_ = DescriptorProto_descriptor_->nested_type(1); + static const int DescriptorProto_ReservedRange_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ReservedRange, start_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ReservedRange, end_), + }; + DescriptorProto_ReservedRange_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + DescriptorProto_ReservedRange_descriptor_, + DescriptorProto_ReservedRange::default_instance_, + DescriptorProto_ReservedRange_offsets_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ReservedRange, _has_bits_[0]), + -1, + -1, + sizeof(DescriptorProto_ReservedRange), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ReservedRange, _internal_metadata_), + -1); FieldDescriptorProto_descriptor_ = file->message_type(3); static const int FieldDescriptorProto_offsets_[9] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, name_), @@ -289,7 +311,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, _internal_metadata_), -1); FileOptions_descriptor_ = file->message_type(9); - static const int FileOptions_offsets_[14] = { + static const int FileOptions_offsets_[15] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_package_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_outer_classname_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_multiple_files_), @@ -303,6 +325,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, deprecated_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, cc_enable_arenas_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, objc_class_prefix_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, csharp_namespace_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, uninterpreted_option_), }; FileOptions_reflection_ = @@ -337,9 +360,10 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _internal_metadata_), -1); FieldOptions_descriptor_ = file->message_type(11); - static const int FieldOptions_offsets_[6] = { + static const int FieldOptions_offsets_[7] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, ctype_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, packed_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, jstype_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, lazy_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, deprecated_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, weak_), @@ -357,6 +381,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, _internal_metadata_), -1); FieldOptions_CType_descriptor_ = FieldOptions_descriptor_->enum_type(0); + FieldOptions_JSType_descriptor_ = FieldOptions_descriptor_->enum_type(1); EnumOptions_descriptor_ = file->message_type(12); static const int EnumOptions_offsets_[3] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, allow_alias_), @@ -514,6 +539,8 @@ void protobuf_RegisterTypes(const ::std::string&) { ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( DescriptorProto_ExtensionRange_descriptor_, &DescriptorProto_ExtensionRange::default_instance()); ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + DescriptorProto_ReservedRange_descriptor_, &DescriptorProto_ReservedRange::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( FieldDescriptorProto_descriptor_, &FieldDescriptorProto::default_instance()); ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( OneofDescriptorProto_descriptor_, &OneofDescriptorProto::default_instance()); @@ -560,6 +587,8 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto() { delete DescriptorProto_reflection_; delete DescriptorProto_ExtensionRange::default_instance_; delete DescriptorProto_ExtensionRange_reflection_; + delete DescriptorProto_ReservedRange::default_instance_; + delete DescriptorProto_ReservedRange_reflection_; delete FieldDescriptorProto::default_instance_; delete FieldDescriptorProto_reflection_; delete OneofDescriptorProto::default_instance_; @@ -618,7 +647,7 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() { "\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\"\344\003\n\017DescriptorProto\022\014\n\004name\030\001 \001(\t\0224\n\005" + "(\t\"\360\004\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" @@ -629,102 +658,111 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() { "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\032,\n\016ExtensionRange\022\r\n\005start\030\001 \001(\005\022\013\n\003" - "end\030\002 \001(\005\"\251\005\n\024FieldDescriptorProto\022\014\n\004na" - "me\030\001 \001(\t\022\016\n\006number\030\003 \001(\005\022:\n\005label\030\004 \001(\0162" - "+.google.protobuf.FieldDescriptorProto.L" - "abel\0228\n\004type\030\005 \001(\0162*.google.protobuf.Fie" - "ldDescriptorProto.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.\n\007options\030\010 \001(\013" - "2\035.google.protobuf.FieldOptions\"\266\002\n\004Type" - "\022\017\n\013TYPE_DOUBLE\020\001\022\016\n\nTYPE_FLOAT\020\002\022\016\n\nTYP" - "E_INT64\020\003\022\017\n\013TYPE_UINT64\020\004\022\016\n\nTYPE_INT32" - "\020\005\022\020\n\014TYPE_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_G" - "ROUP\020\n\022\020\n\014TYPE_MESSAGE\020\013\022\016\n\nTYPE_BYTES\020\014" - "\022\017\n\013TYPE_UINT32\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_S" - "INT32\020\021\022\017\n\013TYPE_SINT64\020\022\"C\n\005Label\022\022\n\016LAB" - "EL_OPTIONAL\020\001\022\022\n\016LABEL_REQUIRED\020\002\022\022\n\016LAB" - "EL_REPEATED\020\003\"$\n\024OneofDescriptorProto\022\014\n" - "\004name\030\001 \001(\t\"\214\001\n\023EnumDescriptorProto\022\014\n\004n" - "ame\030\001 \001(\t\0228\n\005value\030\002 \003(\0132).google.protob" - "uf.EnumValueDescriptorProto\022-\n\007options\030\003" - " \001(\0132\034.google.protobuf.EnumOptions\"l\n\030En" - "umValueDescriptorProto\022\014\n\004name\030\001 \001(\t\022\016\n\006" - "number\030\002 \001(\005\0222\n\007options\030\003 \001(\0132!.google.p" - "rotobuf.EnumValueOptions\"\220\001\n\026ServiceDesc" - "riptorProto\022\014\n\004name\030\001 \001(\t\0226\n\006method\030\002 \003(" - "\0132&.google.protobuf.MethodDescriptorProt" - "o\0220\n\007options\030\003 \001(\0132\037.google.protobuf.Ser" - "viceOptions\"\301\001\n\025MethodDescriptorProto\022\014\n" - "\004name\030\001 \001(\t\022\022\n\ninput_type\030\002 \001(\t\022\023\n\013outpu" - "t_type\030\003 \001(\t\022/\n\007options\030\004 \001(\0132\036.google.p" - "rotobuf.MethodOptions\022\037\n\020client_streamin" - "g\030\005 \001(\010:\005false\022\037\n\020server_streaming\030\006 \001(\010" - ":\005false\"\347\004\n\013FileOptions\022\024\n\014java_package\030" - "\001 \001(\t\022\034\n\024java_outer_classname\030\010 \001(\t\022\"\n\023j" - "ava_multiple_files\030\n \001(\010:\005false\022,\n\035java_" - "generate_equals_and_hash\030\024 \001(\010:\005false\022%\n" - "\026java_string_check_utf8\030\033 \001(\010:\005false\022F\n\014" - "optimize_for\030\t \001(\0162).google.protobuf.Fil" - "eOptions.OptimizeMode:\005SPEED\022\022\n\ngo_packa" - "ge\030\013 \001(\t\022\"\n\023cc_generic_services\030\020 \001(\010:\005f" - "alse\022$\n\025java_generic_services\030\021 \001(\010:\005fal" - "se\022\"\n\023py_generic_services\030\022 \001(\010:\005false\022\031" - "\n\ndeprecated\030\027 \001(\010:\005false\022\037\n\020cc_enable_a" - "renas\030\037 \001(\010:\005false\022\031\n\021objc_class_prefix\030" - "$ \001(\t\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.g" - "oogle.protobuf.UninterpretedOption\":\n\014Op" - "timizeMode\022\t\n\005SPEED\020\001\022\r\n\tCODE_SIZE\020\002\022\020\n\014" - "LITE_RUNTIME\020\003*\t\010\350\007\020\200\200\200\200\002\"\346\001\n\016MessageOpt" - "ions\022&\n\027message_set_wire_format\030\001 \001(\010:\005f" - "alse\022.\n\037no_standard_descriptor_accessor\030" - "\002 \001(\010:\005false\022\031\n\ndeprecated\030\003 \001(\010:\005false\022" - "\021\n\tmap_entry\030\007 \001(\010\022C\n\024uninterpreted_opti" - "on\030\347\007 \003(\0132$.google.protobuf.Uninterprete" - "dOption*\t\010\350\007\020\200\200\200\200\002\"\240\002\n\014FieldOptions\022:\n\005c" - "type\030\001 \001(\0162#.google.protobuf.FieldOption" - "s.CType:\006STRING\022\016\n\006packed\030\002 \001(\010\022\023\n\004lazy\030" - "\005 \001(\010:\005false\022\031\n\ndeprecated\030\003 \001(\010:\005false\022" - "\023\n\004weak\030\n \001(\010:\005false\022C\n\024uninterpreted_op" - "tion\030\347\007 \003(\0132$.google.protobuf.Uninterpre" - "tedOption\"/\n\005CType\022\n\n\006STRING\020\000\022\010\n\004CORD\020\001" - "\022\020\n\014STRING_PIECE\020\002*\t\010\350\007\020\200\200\200\200\002\"\215\001\n\013EnumOp" - "tions\022\023\n\013allow_alias\030\002 \001(\010\022\031\n\ndeprecated" - "\030\003 \001(\010:\005false\022C\n\024uninterpreted_option\030\347\007" - " \003(\0132$.google.protobuf.UninterpretedOpti" - "on*\t\010\350\007\020\200\200\200\200\002\"}\n\020EnumValueOptions\022\031\n\ndep" - "recated\030\001 \001(\010:\005false\022C\n\024uninterpreted_op" - "tion\030\347\007 \003(\0132$.google.protobuf.Uninterpre" - "tedOption*\t\010\350\007\020\200\200\200\200\002\"{\n\016ServiceOptions\022\031" - "\n\ndeprecated\030! \001(\010:\005false\022C\n\024uninterpret" - "ed_option\030\347\007 \003(\0132$.google.protobuf.Unint" - "erpretedOption*\t\010\350\007\020\200\200\200\200\002\"z\n\rMethodOptio" - "ns\022\031\n\ndeprecated\030! \001(\010:\005false\022C\n\024uninter" - "preted_option\030\347\007 \003(\0132$.google.protobuf.U" - "ninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"\236\002\n\023Uninte" - "rpretedOption\022;\n\004name\030\002 \003(\0132-.google.pro" - "tobuf.UninterpretedOption.NamePart\022\030\n\020id" - "entifier_value\030\003 \001(\t\022\032\n\022positive_int_val" - "ue\030\004 \001(\004\022\032\n\022negative_int_value\030\005 \001(\003\022\024\n\014" - "double_value\030\006 \001(\001\022\024\n\014string_value\030\007 \001(\014" - "\022\027\n\017aggregate_value\030\010 \001(\t\0323\n\010NamePart\022\021\n" - "\tname_part\030\001 \002(\t\022\024\n\014is_extension\030\002 \002(\010\"\325" - "\001\n\016SourceCodeInfo\022:\n\010location\030\001 \003(\0132(.go" - "ogle.protobuf.SourceCodeInfo.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\021trai" - "ling_comments\030\004 \001(\t\022!\n\031leading_detached_" - "comments\030\006 \003(\tB)\n\023com.google.protobufB\020D" - "escriptorProtosH\001", 4617); + "ons\022F\n\016reserved_range\030\t \003(\0132..google.pro" + "tobuf.DescriptorProto.ReservedRange\022\025\n\rr" + "eserved_name\030\n \003(\t\032,\n\016ExtensionRange\022\r\n\005" + "start\030\001 \001(\005\022\013\n\003end\030\002 \001(\005\032+\n\rReservedRang" + "e\022\r\n\005start\030\001 \001(\005\022\013\n\003end\030\002 \001(\005\"\251\005\n\024FieldD" + "escriptorProto\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.Fi" + "eldDescriptorProto.Label\0228\n\004type\030\005 \001(\0162*" + ".google.protobuf.FieldDescriptorProto.Ty" + "pe\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.\n\007options\030\010 \001(\0132\035.google.protobuf.F" + "ieldOptions\"\266\002\n\004Type\022\017\n\013TYPE_DOUBLE\020\001\022\016\n" + "\nTYPE_FLOAT\020\002\022\016\n\nTYPE_INT64\020\003\022\017\n\013TYPE_UI" + "NT64\020\004\022\016\n\nTYPE_INT32\020\005\022\020\n\014TYPE_FIXED64\020\006" + "\022\020\n\014TYPE_FIXED32\020\007\022\r\n\tTYPE_BOOL\020\010\022\017\n\013TYP" + "E_STRING\020\t\022\016\n\nTYPE_GROUP\020\n\022\020\n\014TYPE_MESSA" + "GE\020\013\022\016\n\nTYPE_BYTES\020\014\022\017\n\013TYPE_UINT32\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\013TYPE_SINT" + "64\020\022\"C\n\005Label\022\022\n\016LABEL_OPTIONAL\020\001\022\022\n\016LAB" + "EL_REQUIRED\020\002\022\022\n\016LABEL_REPEATED\020\003\"$\n\024One" + "ofDescriptorProto\022\014\n\004name\030\001 \001(\t\"\214\001\n\023Enum" + "DescriptorProto\022\014\n\004name\030\001 \001(\t\0228\n\005value\030\002" + " \003(\0132).google.protobuf.EnumValueDescript" + "orProto\022-\n\007options\030\003 \001(\0132\034.google.protob" + "uf.EnumOptions\"l\n\030EnumValueDescriptorPro" + "to\022\014\n\004name\030\001 \001(\t\022\016\n\006number\030\002 \001(\005\0222\n\007opti" + "ons\030\003 \001(\0132!.google.protobuf.EnumValueOpt" + "ions\"\220\001\n\026ServiceDescriptorProto\022\014\n\004name\030" + "\001 \001(\t\0226\n\006method\030\002 \003(\0132&.google.protobuf." + "MethodDescriptorProto\0220\n\007options\030\003 \001(\0132\037" + ".google.protobuf.ServiceOptions\"\301\001\n\025Meth" + "odDescriptorProto\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\007opti" + "ons\030\004 \001(\0132\036.google.protobuf.MethodOption" + "s\022\037\n\020client_streaming\030\005 \001(\010:\005false\022\037\n\020se" + "rver_streaming\030\006 \001(\010:\005false\"\201\005\n\013FileOpti" + "ons\022\024\n\014java_package\030\001 \001(\t\022\034\n\024java_outer_" + "classname\030\010 \001(\t\022\"\n\023java_multiple_files\030\n" + " \001(\010:\005false\022,\n\035java_generate_equals_and_" + "hash\030\024 \001(\010:\005false\022%\n\026java_string_check_u" + "tf8\030\033 \001(\010:\005false\022F\n\014optimize_for\030\t \001(\0162)" + ".google.protobuf.FileOptions.OptimizeMod" + "e:\005SPEED\022\022\n\ngo_package\030\013 \001(\t\022\"\n\023cc_gener" + "ic_services\030\020 \001(\010:\005false\022$\n\025java_generic" + "_services\030\021 \001(\010:\005false\022\"\n\023py_generic_ser" + "vices\030\022 \001(\010:\005false\022\031\n\ndeprecated\030\027 \001(\010:\005" + "false\022\037\n\020cc_enable_arenas\030\037 \001(\010:\005false\022\031" + "\n\021objc_class_prefix\030$ \001(\t\022\030\n\020csharp_name" + "space\030% \001(\t\022C\n\024uninterpreted_option\030\347\007 \003" + "(\0132$.google.protobuf.UninterpretedOption" + "\":\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\002\"\346\001\n\016Mess" + "ageOptions\022&\n\027message_set_wire_format\030\001 " + "\001(\010:\005false\022.\n\037no_standard_descriptor_acc" + "essor\030\002 \001(\010:\005false\022\031\n\ndeprecated\030\003 \001(\010:\005" + "false\022\021\n\tmap_entry\030\007 \001(\010\022C\n\024uninterprete" + "d_option\030\347\007 \003(\0132$.google.protobuf.Uninte" + "rpretedOption*\t\010\350\007\020\200\200\200\200\002\"\230\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\002\"\215\001\n\013" + "EnumOptions\022\023\n\013allow_alias\030\002 \001(\010\022\031\n\ndepr" + "ecated\030\003 \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\"}\n\020EnumValueOptions\022" + "\031\n\ndeprecated\030\001 \001(\010:\005false\022C\n\024uninterpre" + "ted_option\030\347\007 \003(\0132$.google.protobuf.Unin" + "terpretedOption*\t\010\350\007\020\200\200\200\200\002\"{\n\016ServiceOpt" + "ions\022\031\n\ndeprecated\030! \001(\010:\005false\022C\n\024unint" + "erpreted_option\030\347\007 \003(\0132$.google.protobuf" + ".UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"z\n\rMetho" + "dOptions\022\031\n\ndeprecated\030! \001(\010:\005false\022C\n\024u" + "ninterpreted_option\030\347\007 \003(\0132$.google.prot" + "obuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"\236\002\n\023" + "UninterpretedOption\022;\n\004name\030\002 \003(\0132-.goog" + "le.protobuf.UninterpretedOption.NamePart" + "\022\030\n\020identifier_value\030\003 \001(\t\022\032\n\022positive_i" + "nt_value\030\004 \001(\004\022\032\n\022negative_int_value\030\005 \001" + "(\003\022\024\n\014double_value\030\006 \001(\001\022\024\n\014string_value" + "\030\007 \001(\014\022\027\n\017aggregate_value\030\010 \001(\t\0323\n\010NameP" + "art\022\021\n\tname_part\030\001 \002(\t\022\024\n\014is_extension\030\002" + " \002(\010\"\325\001\n\016SourceCodeInfo\022:\n\010location\030\001 \003(" + "\0132(.google.protobuf.SourceCodeInfo.Locat" + "ion\032\206\001\n\010Location\022\020\n\004path\030\001 \003(\005B\002\020\001\022\020\n\004sp" + "an\030\002 \003(\005B\002\020\001\022\030\n\020leading_comments\030\003 \001(\t\022\031" + "\n\021trailing_comments\030\004 \001(\t\022!\n\031leading_det" + "ached_comments\030\006 \003(\tBY\n\023com.google.proto" + "bufB\020DescriptorProtosH\001\242\002\003GPB\252\002\'Google.P" + "rotocolBuffers.DescriptorProtos", 4951); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( "google/protobuf/descriptor.proto", &protobuf_RegisterTypes); FileDescriptorSet::default_instance_ = new FileDescriptorSet(); FileDescriptorProto::default_instance_ = new FileDescriptorProto(); DescriptorProto::default_instance_ = new DescriptorProto(); DescriptorProto_ExtensionRange::default_instance_ = new DescriptorProto_ExtensionRange(); + DescriptorProto_ReservedRange::default_instance_ = new DescriptorProto_ReservedRange(); FieldDescriptorProto::default_instance_ = new FieldDescriptorProto(); OneofDescriptorProto::default_instance_ = new OneofDescriptorProto(); EnumDescriptorProto::default_instance_ = new EnumDescriptorProto(); @@ -746,6 +784,7 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() { FileDescriptorProto::default_instance_->InitAsDefaultInstance(); DescriptorProto::default_instance_->InitAsDefaultInstance(); DescriptorProto_ExtensionRange::default_instance_->InitAsDefaultInstance(); + DescriptorProto_ReservedRange::default_instance_->InitAsDefaultInstance(); FieldDescriptorProto::default_instance_->InitAsDefaultInstance(); OneofDescriptorProto::default_instance_->InitAsDefaultInstance(); EnumDescriptorProto::default_instance_->InitAsDefaultInstance(); @@ -790,7 +829,7 @@ const int FileDescriptorSet::kFileFieldNumber; #endif // !_MSC_VER FileDescriptorSet::FileDescriptorSet() - : ::google::protobuf::Message() , _internal_metadata_(NULL) { + : ::google::protobuf::Message(), _internal_metadata_(NULL) { SharedCtor(); // @@protoc_insertion_point(constructor:google.protobuf.FileDescriptorSet) } @@ -867,13 +906,15 @@ bool FileDescriptorSet::MergePartialFromCodedStream( // repeated .google.protobuf.FileDescriptorProto file = 1; case 1: { if (tag == 10) { - parse_file: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + DO_(input->IncrementRecursionDepth()); + parse_loop_file: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( input, add_file())); } else { goto handle_unusual; } - if (input->ExpectTag(10)) goto parse_file; + if (input->ExpectTag(10)) goto parse_loop_file; + input->UnsafeDecrementRecursionDepth(); if (input->ExpectAtEnd()) goto success; break; } @@ -958,9 +999,9 @@ int FileDescriptorSet::ByteSize() const { void FileDescriptorSet::MergeFrom(const ::google::protobuf::Message& from) { if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - const FileDescriptorSet* source = - ::google::protobuf::internal::dynamic_cast_if_available<const FileDescriptorSet*>( - &from); + const FileDescriptorSet* source = + ::google::protobuf::internal::DynamicCastToGenerated<const FileDescriptorSet>( + &from); if (source == NULL) { ::google::protobuf::internal::ReflectionOps::Merge(from, this); } else { @@ -1017,10 +1058,10 @@ void FileDescriptorSet::InternalSwap(FileDescriptorSet* other) { // FileDescriptorSet // repeated .google.protobuf.FileDescriptorProto file = 1; - int FileDescriptorSet::file_size() const { +int FileDescriptorSet::file_size() const { return file_.size(); } - void FileDescriptorSet::clear_file() { +void FileDescriptorSet::clear_file() { file_.Clear(); } const ::google::protobuf::FileDescriptorProto& FileDescriptorSet::file(int index) const { @@ -1066,7 +1107,7 @@ const int FileDescriptorProto::kSyntaxFieldNumber; #endif // !_MSC_VER FileDescriptorProto::FileDescriptorProto() - : ::google::protobuf::Message() , _internal_metadata_(NULL) { + : ::google::protobuf::Message(), _internal_metadata_(NULL) { SharedCtor(); // @@protoc_insertion_point(constructor:google.protobuf.FileDescriptorProto) } @@ -1136,7 +1177,7 @@ FileDescriptorProto* FileDescriptorProto::New(::google::protobuf::Arena* arena) } void FileDescriptorProto::Clear() { - if (_has_bits_[0 / 32] & 3) { + if (_has_bits_[0 / 32] & 3u) { if (has_name()) { name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); } @@ -1144,7 +1185,7 @@ void FileDescriptorProto::Clear() { package_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); } } - if (_has_bits_[8 / 32] & 3584) { + if (_has_bits_[8 / 32] & 3584u) { if (has_options()) { if (options_ != NULL) options_->::google::protobuf::FileOptions::Clear(); } @@ -1234,54 +1275,63 @@ bool FileDescriptorProto::MergePartialFromCodedStream( case 4: { if (tag == 34) { parse_message_type: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + DO_(input->IncrementRecursionDepth()); + parse_loop_message_type: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( input, add_message_type())); } else { goto handle_unusual; } - if (input->ExpectTag(34)) goto parse_message_type; - if (input->ExpectTag(42)) goto parse_enum_type; + if (input->ExpectTag(34)) goto parse_loop_message_type; + if (input->ExpectTag(42)) goto parse_loop_enum_type; + input->UnsafeDecrementRecursionDepth(); break; } // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; case 5: { if (tag == 42) { - parse_enum_type: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + DO_(input->IncrementRecursionDepth()); + parse_loop_enum_type: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( input, add_enum_type())); } else { goto handle_unusual; } - if (input->ExpectTag(42)) goto parse_enum_type; - if (input->ExpectTag(50)) goto parse_service; + if (input->ExpectTag(42)) goto parse_loop_enum_type; + if (input->ExpectTag(50)) goto parse_loop_service; + input->UnsafeDecrementRecursionDepth(); break; } // repeated .google.protobuf.ServiceDescriptorProto service = 6; case 6: { if (tag == 50) { - parse_service: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + DO_(input->IncrementRecursionDepth()); + parse_loop_service: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( input, add_service())); } else { goto handle_unusual; } - if (input->ExpectTag(50)) goto parse_service; - if (input->ExpectTag(58)) goto parse_extension; + if (input->ExpectTag(50)) goto parse_loop_service; + if (input->ExpectTag(58)) goto parse_loop_extension; + input->UnsafeDecrementRecursionDepth(); break; } // repeated .google.protobuf.FieldDescriptorProto extension = 7; case 7: { if (tag == 58) { - parse_extension: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + DO_(input->IncrementRecursionDepth()); + parse_loop_extension: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( input, add_extension())); } else { goto handle_unusual; } - if (input->ExpectTag(58)) goto parse_extension; + if (input->ExpectTag(58)) goto parse_loop_extension; + input->UnsafeDecrementRecursionDepth(); if (input->ExpectTag(66)) goto parse_options; break; } @@ -1709,9 +1759,9 @@ int FileDescriptorProto::ByteSize() const { void FileDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) { if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - const FileDescriptorProto* source = - ::google::protobuf::internal::dynamic_cast_if_available<const FileDescriptorProto*>( - &from); + const FileDescriptorProto* source = + ::google::protobuf::internal::DynamicCastToGenerated<const FileDescriptorProto>( + &from); if (source == NULL) { ::google::protobuf::internal::ReflectionOps::Merge(from, this); } else { @@ -1813,16 +1863,16 @@ void FileDescriptorProto::InternalSwap(FileDescriptorProto* other) { // FileDescriptorProto // optional string name = 1; - bool FileDescriptorProto::has_name() const { +bool FileDescriptorProto::has_name() const { return (_has_bits_[0] & 0x00000001u) != 0; } - void FileDescriptorProto::set_has_name() { +void FileDescriptorProto::set_has_name() { _has_bits_[0] |= 0x00000001u; } - void FileDescriptorProto::clear_has_name() { +void FileDescriptorProto::clear_has_name() { _has_bits_[0] &= ~0x00000001u; } - void FileDescriptorProto::clear_name() { +void FileDescriptorProto::clear_name() { name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); clear_has_name(); } @@ -1866,16 +1916,16 @@ void FileDescriptorProto::InternalSwap(FileDescriptorProto* other) { } // optional string package = 2; - bool FileDescriptorProto::has_package() const { +bool FileDescriptorProto::has_package() const { return (_has_bits_[0] & 0x00000002u) != 0; } - void FileDescriptorProto::set_has_package() { +void FileDescriptorProto::set_has_package() { _has_bits_[0] |= 0x00000002u; } - void FileDescriptorProto::clear_has_package() { +void FileDescriptorProto::clear_has_package() { _has_bits_[0] &= ~0x00000002u; } - void FileDescriptorProto::clear_package() { +void FileDescriptorProto::clear_package() { package_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); clear_has_package(); } @@ -1919,10 +1969,10 @@ void FileDescriptorProto::InternalSwap(FileDescriptorProto* other) { } // repeated string dependency = 3; - int FileDescriptorProto::dependency_size() const { +int FileDescriptorProto::dependency_size() const { return dependency_.size(); } - void FileDescriptorProto::clear_dependency() { +void FileDescriptorProto::clear_dependency() { dependency_.Clear(); } const ::std::string& FileDescriptorProto::dependency(int index) const { @@ -1973,10 +2023,10 @@ FileDescriptorProto::mutable_dependency() { } // repeated int32 public_dependency = 10; - int FileDescriptorProto::public_dependency_size() const { +int FileDescriptorProto::public_dependency_size() const { return public_dependency_.size(); } - void FileDescriptorProto::clear_public_dependency() { +void FileDescriptorProto::clear_public_dependency() { public_dependency_.Clear(); } ::google::protobuf::int32 FileDescriptorProto::public_dependency(int index) const { @@ -2003,10 +2053,10 @@ FileDescriptorProto::mutable_public_dependency() { } // repeated int32 weak_dependency = 11; - int FileDescriptorProto::weak_dependency_size() const { +int FileDescriptorProto::weak_dependency_size() const { return weak_dependency_.size(); } - void FileDescriptorProto::clear_weak_dependency() { +void FileDescriptorProto::clear_weak_dependency() { weak_dependency_.Clear(); } ::google::protobuf::int32 FileDescriptorProto::weak_dependency(int index) const { @@ -2033,10 +2083,10 @@ FileDescriptorProto::mutable_weak_dependency() { } // repeated .google.protobuf.DescriptorProto message_type = 4; - int FileDescriptorProto::message_type_size() const { +int FileDescriptorProto::message_type_size() const { return message_type_.size(); } - void FileDescriptorProto::clear_message_type() { +void FileDescriptorProto::clear_message_type() { message_type_.Clear(); } const ::google::protobuf::DescriptorProto& FileDescriptorProto::message_type(int index) const { @@ -2063,10 +2113,10 @@ FileDescriptorProto::mutable_message_type() { } // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; - int FileDescriptorProto::enum_type_size() const { +int FileDescriptorProto::enum_type_size() const { return enum_type_.size(); } - void FileDescriptorProto::clear_enum_type() { +void FileDescriptorProto::clear_enum_type() { enum_type_.Clear(); } const ::google::protobuf::EnumDescriptorProto& FileDescriptorProto::enum_type(int index) const { @@ -2093,10 +2143,10 @@ FileDescriptorProto::mutable_enum_type() { } // repeated .google.protobuf.ServiceDescriptorProto service = 6; - int FileDescriptorProto::service_size() const { +int FileDescriptorProto::service_size() const { return service_.size(); } - void FileDescriptorProto::clear_service() { +void FileDescriptorProto::clear_service() { service_.Clear(); } const ::google::protobuf::ServiceDescriptorProto& FileDescriptorProto::service(int index) const { @@ -2123,10 +2173,10 @@ FileDescriptorProto::mutable_service() { } // repeated .google.protobuf.FieldDescriptorProto extension = 7; - int FileDescriptorProto::extension_size() const { +int FileDescriptorProto::extension_size() const { return extension_.size(); } - void FileDescriptorProto::clear_extension() { +void FileDescriptorProto::clear_extension() { extension_.Clear(); } const ::google::protobuf::FieldDescriptorProto& FileDescriptorProto::extension(int index) const { @@ -2153,16 +2203,16 @@ FileDescriptorProto::mutable_extension() { } // optional .google.protobuf.FileOptions options = 8; - bool FileDescriptorProto::has_options() const { +bool FileDescriptorProto::has_options() const { return (_has_bits_[0] & 0x00000200u) != 0; } - void FileDescriptorProto::set_has_options() { +void FileDescriptorProto::set_has_options() { _has_bits_[0] |= 0x00000200u; } - void FileDescriptorProto::clear_has_options() { +void FileDescriptorProto::clear_has_options() { _has_bits_[0] &= ~0x00000200u; } - void FileDescriptorProto::clear_options() { +void FileDescriptorProto::clear_options() { if (options_ != NULL) options_->::google::protobuf::FileOptions::Clear(); clear_has_options(); } @@ -2196,16 +2246,16 @@ FileDescriptorProto::mutable_extension() { } // optional .google.protobuf.SourceCodeInfo source_code_info = 9; - bool FileDescriptorProto::has_source_code_info() const { +bool FileDescriptorProto::has_source_code_info() const { return (_has_bits_[0] & 0x00000400u) != 0; } - void FileDescriptorProto::set_has_source_code_info() { +void FileDescriptorProto::set_has_source_code_info() { _has_bits_[0] |= 0x00000400u; } - void FileDescriptorProto::clear_has_source_code_info() { +void FileDescriptorProto::clear_has_source_code_info() { _has_bits_[0] &= ~0x00000400u; } - void FileDescriptorProto::clear_source_code_info() { +void FileDescriptorProto::clear_source_code_info() { if (source_code_info_ != NULL) source_code_info_->::google::protobuf::SourceCodeInfo::Clear(); clear_has_source_code_info(); } @@ -2239,16 +2289,16 @@ FileDescriptorProto::mutable_extension() { } // optional string syntax = 12; - bool FileDescriptorProto::has_syntax() const { +bool FileDescriptorProto::has_syntax() const { return (_has_bits_[0] & 0x00000800u) != 0; } - void FileDescriptorProto::set_has_syntax() { +void FileDescriptorProto::set_has_syntax() { _has_bits_[0] |= 0x00000800u; } - void FileDescriptorProto::clear_has_syntax() { +void FileDescriptorProto::clear_has_syntax() { _has_bits_[0] &= ~0x00000800u; } - void FileDescriptorProto::clear_syntax() { +void FileDescriptorProto::clear_syntax() { syntax_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); clear_has_syntax(); } @@ -2301,7 +2351,7 @@ const int DescriptorProto_ExtensionRange::kEndFieldNumber; #endif // !_MSC_VER DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange() - : ::google::protobuf::Message() , _internal_metadata_(NULL) { + : ::google::protobuf::Message(), _internal_metadata_(NULL) { SharedCtor(); // @@protoc_insertion_point(constructor:google.protobuf.DescriptorProto.ExtensionRange) } @@ -2513,9 +2563,9 @@ int DescriptorProto_ExtensionRange::ByteSize() const { void DescriptorProto_ExtensionRange::MergeFrom(const ::google::protobuf::Message& from) { if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - const DescriptorProto_ExtensionRange* source = - ::google::protobuf::internal::dynamic_cast_if_available<const DescriptorProto_ExtensionRange*>( - &from); + const DescriptorProto_ExtensionRange* source = + ::google::protobuf::internal::DynamicCastToGenerated<const DescriptorProto_ExtensionRange>( + &from); if (source == NULL) { ::google::protobuf::internal::ReflectionOps::Merge(from, this); } else { @@ -2579,6 +2629,289 @@ void DescriptorProto_ExtensionRange::InternalSwap(DescriptorProto_ExtensionRange // ------------------------------------------------------------------- #ifndef _MSC_VER +const int DescriptorProto_ReservedRange::kStartFieldNumber; +const int DescriptorProto_ReservedRange::kEndFieldNumber; +#endif // !_MSC_VER + +DescriptorProto_ReservedRange::DescriptorProto_ReservedRange() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:google.protobuf.DescriptorProto.ReservedRange) +} + +void DescriptorProto_ReservedRange::InitAsDefaultInstance() { +} + +DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:google.protobuf.DescriptorProto.ReservedRange) +} + +void DescriptorProto_ReservedRange::SharedCtor() { + _cached_size_ = 0; + start_ = 0; + end_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +DescriptorProto_ReservedRange::~DescriptorProto_ReservedRange() { + // @@protoc_insertion_point(destructor:google.protobuf.DescriptorProto.ReservedRange) + SharedDtor(); +} + +void DescriptorProto_ReservedRange::SharedDtor() { + if (this != default_instance_) { + } +} + +void DescriptorProto_ReservedRange::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* DescriptorProto_ReservedRange::descriptor() { + protobuf_AssignDescriptorsOnce(); + return DescriptorProto_ReservedRange_descriptor_; +} + +const DescriptorProto_ReservedRange& DescriptorProto_ReservedRange::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + return *default_instance_; +} + +DescriptorProto_ReservedRange* DescriptorProto_ReservedRange::default_instance_ = NULL; + +DescriptorProto_ReservedRange* DescriptorProto_ReservedRange::New(::google::protobuf::Arena* arena) const { + DescriptorProto_ReservedRange* n = new DescriptorProto_ReservedRange; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void DescriptorProto_ReservedRange::Clear() { +#define ZR_HELPER_(f) reinterpret_cast<char*>(\ + &reinterpret_cast<DescriptorProto_ReservedRange*>(16)->f) + +#define ZR_(first, last) do {\ + ::memset(&first, 0,\ + ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\ +} while (0) + + ZR_(start_, end_); + +#undef ZR_HELPER_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + if (_internal_metadata_.have_unknown_fields()) { + mutable_unknown_fields()->Clear(); + } +} + +bool DescriptorProto_ReservedRange::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:google.protobuf.DescriptorProto.ReservedRange) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional int32 start = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &start_))); + set_has_start(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_end; + break; + } + + // optional int32 end = 2; + case 2: { + if (tag == 16) { + parse_end: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &end_))); + set_has_end(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:google.protobuf.DescriptorProto.ReservedRange) + return true; +failure: + // @@protoc_insertion_point(parse_failure:google.protobuf.DescriptorProto.ReservedRange) + return false; +#undef DO_ +} + +void DescriptorProto_ReservedRange::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:google.protobuf.DescriptorProto.ReservedRange) + // optional int32 start = 1; + if (has_start()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->start(), output); + } + + // optional int32 end = 2; + if (has_end()) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->end(), output); + } + + if (_internal_metadata_.have_unknown_fields()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:google.protobuf.DescriptorProto.ReservedRange) +} + +::google::protobuf::uint8* DescriptorProto_ReservedRange::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DescriptorProto.ReservedRange) + // optional int32 start = 1; + if (has_start()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->start(), target); + } + + // optional int32 end = 2; + if (has_end()) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->end(), target); + } + + if (_internal_metadata_.have_unknown_fields()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.DescriptorProto.ReservedRange) + return target; +} + +int DescriptorProto_ReservedRange::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & 3) { + // optional int32 start = 1; + if (has_start()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->start()); + } + + // optional int32 end = 2; + if (has_end()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->end()); + } + + } + if (_internal_metadata_.have_unknown_fields()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void DescriptorProto_ReservedRange::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const DescriptorProto_ReservedRange* source = + ::google::protobuf::internal::DynamicCastToGenerated<const DescriptorProto_ReservedRange>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void DescriptorProto_ReservedRange::MergeFrom(const DescriptorProto_ReservedRange& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_start()) { + set_start(from.start()); + } + if (from.has_end()) { + set_end(from.end()); + } + } + if (from._internal_metadata_.have_unknown_fields()) { + mutable_unknown_fields()->MergeFrom(from.unknown_fields()); + } +} + +void DescriptorProto_ReservedRange::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void DescriptorProto_ReservedRange::CopyFrom(const DescriptorProto_ReservedRange& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool DescriptorProto_ReservedRange::IsInitialized() const { + + return true; +} + +void DescriptorProto_ReservedRange::Swap(DescriptorProto_ReservedRange* other) { + if (other == this) return; + InternalSwap(other); +} +void DescriptorProto_ReservedRange::InternalSwap(DescriptorProto_ReservedRange* other) { + std::swap(start_, other->start_); + std::swap(end_, other->end_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata DescriptorProto_ReservedRange::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = DescriptorProto_ReservedRange_descriptor_; + metadata.reflection = DescriptorProto_ReservedRange_reflection_; + return metadata; +} + + +// ------------------------------------------------------------------- + +#ifndef _MSC_VER const int DescriptorProto::kNameFieldNumber; const int DescriptorProto::kFieldFieldNumber; const int DescriptorProto::kExtensionFieldNumber; @@ -2587,10 +2920,12 @@ const int DescriptorProto::kEnumTypeFieldNumber; const int DescriptorProto::kExtensionRangeFieldNumber; const int DescriptorProto::kOneofDeclFieldNumber; const int DescriptorProto::kOptionsFieldNumber; +const int DescriptorProto::kReservedRangeFieldNumber; +const int DescriptorProto::kReservedNameFieldNumber; #endif // !_MSC_VER DescriptorProto::DescriptorProto() - : ::google::protobuf::Message() , _internal_metadata_(NULL) { + : ::google::protobuf::Message(), _internal_metadata_(NULL) { SharedCtor(); // @@protoc_insertion_point(constructor:google.protobuf.DescriptorProto) } @@ -2653,7 +2988,7 @@ DescriptorProto* DescriptorProto::New(::google::protobuf::Arena* arena) const { } void DescriptorProto::Clear() { - if (_has_bits_[0 / 32] & 129) { + if (_has_bits_[0 / 32] & 129u) { if (has_name()) { name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); } @@ -2667,6 +3002,8 @@ void DescriptorProto::Clear() { enum_type_.Clear(); extension_range_.Clear(); oneof_decl_.Clear(); + reserved_range_.Clear(); + reserved_name_.Clear(); ::memset(_has_bits_, 0, sizeof(_has_bits_)); if (_internal_metadata_.have_unknown_fields()) { mutable_unknown_fields()->Clear(); @@ -2703,68 +3040,79 @@ bool DescriptorProto::MergePartialFromCodedStream( case 2: { if (tag == 18) { parse_field: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + DO_(input->IncrementRecursionDepth()); + parse_loop_field: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( input, add_field())); } else { goto handle_unusual; } - if (input->ExpectTag(18)) goto parse_field; - if (input->ExpectTag(26)) goto parse_nested_type; + if (input->ExpectTag(18)) goto parse_loop_field; + if (input->ExpectTag(26)) goto parse_loop_nested_type; + input->UnsafeDecrementRecursionDepth(); break; } // repeated .google.protobuf.DescriptorProto nested_type = 3; case 3: { if (tag == 26) { - parse_nested_type: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + DO_(input->IncrementRecursionDepth()); + parse_loop_nested_type: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( input, add_nested_type())); } else { goto handle_unusual; } - if (input->ExpectTag(26)) goto parse_nested_type; - if (input->ExpectTag(34)) goto parse_enum_type; + if (input->ExpectTag(26)) goto parse_loop_nested_type; + if (input->ExpectTag(34)) goto parse_loop_enum_type; + input->UnsafeDecrementRecursionDepth(); break; } // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; case 4: { if (tag == 34) { - parse_enum_type: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + DO_(input->IncrementRecursionDepth()); + parse_loop_enum_type: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( input, add_enum_type())); } else { goto handle_unusual; } - if (input->ExpectTag(34)) goto parse_enum_type; - if (input->ExpectTag(42)) goto parse_extension_range; + if (input->ExpectTag(34)) goto parse_loop_enum_type; + if (input->ExpectTag(42)) goto parse_loop_extension_range; + input->UnsafeDecrementRecursionDepth(); break; } // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; case 5: { if (tag == 42) { - parse_extension_range: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + DO_(input->IncrementRecursionDepth()); + parse_loop_extension_range: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( input, add_extension_range())); } else { goto handle_unusual; } - if (input->ExpectTag(42)) goto parse_extension_range; - if (input->ExpectTag(50)) goto parse_extension; + if (input->ExpectTag(42)) goto parse_loop_extension_range; + if (input->ExpectTag(50)) goto parse_loop_extension; + input->UnsafeDecrementRecursionDepth(); break; } // repeated .google.protobuf.FieldDescriptorProto extension = 6; case 6: { if (tag == 50) { - parse_extension: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + DO_(input->IncrementRecursionDepth()); + parse_loop_extension: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( input, add_extension())); } else { goto handle_unusual; } - if (input->ExpectTag(50)) goto parse_extension; + if (input->ExpectTag(50)) goto parse_loop_extension; + input->UnsafeDecrementRecursionDepth(); if (input->ExpectTag(58)) goto parse_options; break; } @@ -2786,12 +3134,50 @@ bool DescriptorProto::MergePartialFromCodedStream( case 8: { if (tag == 66) { parse_oneof_decl: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + DO_(input->IncrementRecursionDepth()); + parse_loop_oneof_decl: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( input, add_oneof_decl())); } else { goto handle_unusual; } - if (input->ExpectTag(66)) goto parse_oneof_decl; + if (input->ExpectTag(66)) goto parse_loop_oneof_decl; + if (input->ExpectTag(74)) goto parse_loop_reserved_range; + input->UnsafeDecrementRecursionDepth(); + break; + } + + // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9; + case 9: { + if (tag == 74) { + DO_(input->IncrementRecursionDepth()); + parse_loop_reserved_range: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + input, add_reserved_range())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(74)) goto parse_loop_reserved_range; + input->UnsafeDecrementRecursionDepth(); + if (input->ExpectTag(82)) goto parse_reserved_name; + break; + } + + // repeated string reserved_name = 10; + case 10: { + if (tag == 82) { + parse_reserved_name: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->add_reserved_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->reserved_name(this->reserved_name_size() - 1).data(), + this->reserved_name(this->reserved_name_size() - 1).length(), + ::google::protobuf::internal::WireFormat::PARSE, + "google.protobuf.DescriptorProto.reserved_name"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(82)) goto parse_reserved_name; if (input->ExpectAtEnd()) goto success; break; } @@ -2873,6 +3259,22 @@ void DescriptorProto::SerializeWithCachedSizes( 8, this->oneof_decl(i), output); } + // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9; + for (unsigned int i = 0, n = this->reserved_range_size(); i < n; i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 9, this->reserved_range(i), output); + } + + // repeated string reserved_name = 10; + for (int i = 0; i < this->reserved_name_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->reserved_name(i).data(), this->reserved_name(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.DescriptorProto.reserved_name"); + ::google::protobuf::internal::WireFormatLite::WriteString( + 10, this->reserved_name(i), output); + } + if (_internal_metadata_.have_unknown_fields()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( unknown_fields(), output); @@ -2943,6 +3345,23 @@ void DescriptorProto::SerializeWithCachedSizes( 8, this->oneof_decl(i), target); } + // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9; + for (unsigned int i = 0, n = this->reserved_range_size(); i < n; i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 9, this->reserved_range(i), target); + } + + // repeated string reserved_name = 10; + for (int i = 0; i < this->reserved_name_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->reserved_name(i).data(), this->reserved_name(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.DescriptorProto.reserved_name"); + target = ::google::protobuf::internal::WireFormatLite:: + WriteStringToArray(10, this->reserved_name(i), target); + } + if (_internal_metadata_.have_unknown_fields()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( unknown_fields(), target); @@ -3018,6 +3437,21 @@ int DescriptorProto::ByteSize() const { this->oneof_decl(i)); } + // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9; + total_size += 1 * this->reserved_range_size(); + for (int i = 0; i < this->reserved_range_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->reserved_range(i)); + } + + // repeated string reserved_name = 10; + total_size += 1 * this->reserved_name_size(); + for (int i = 0; i < this->reserved_name_size(); i++) { + total_size += ::google::protobuf::internal::WireFormatLite::StringSize( + this->reserved_name(i)); + } + if (_internal_metadata_.have_unknown_fields()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( @@ -3031,9 +3465,9 @@ int DescriptorProto::ByteSize() const { void DescriptorProto::MergeFrom(const ::google::protobuf::Message& from) { if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - const DescriptorProto* source = - ::google::protobuf::internal::dynamic_cast_if_available<const DescriptorProto*>( - &from); + const DescriptorProto* source = + ::google::protobuf::internal::DynamicCastToGenerated<const DescriptorProto>( + &from); if (source == NULL) { ::google::protobuf::internal::ReflectionOps::Merge(from, this); } else { @@ -3049,6 +3483,8 @@ void DescriptorProto::MergeFrom(const DescriptorProto& from) { enum_type_.MergeFrom(from.enum_type_); extension_range_.MergeFrom(from.extension_range_); oneof_decl_.MergeFrom(from.oneof_decl_); + reserved_range_.MergeFrom(from.reserved_range_); + reserved_name_.MergeFrom(from.reserved_name_); if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { if (from.has_name()) { set_has_name(); @@ -3100,6 +3536,8 @@ void DescriptorProto::InternalSwap(DescriptorProto* other) { extension_range_.UnsafeArenaSwap(&other->extension_range_); oneof_decl_.UnsafeArenaSwap(&other->oneof_decl_); std::swap(options_, other->options_); + reserved_range_.UnsafeArenaSwap(&other->reserved_range_); + reserved_name_.UnsafeArenaSwap(&other->reserved_name_); std::swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); std::swap(_cached_size_, other->_cached_size_); @@ -3117,16 +3555,16 @@ void DescriptorProto::InternalSwap(DescriptorProto* other) { // DescriptorProto_ExtensionRange // optional int32 start = 1; - bool DescriptorProto_ExtensionRange::has_start() const { +bool DescriptorProto_ExtensionRange::has_start() const { return (_has_bits_[0] & 0x00000001u) != 0; } - void DescriptorProto_ExtensionRange::set_has_start() { +void DescriptorProto_ExtensionRange::set_has_start() { _has_bits_[0] |= 0x00000001u; } - void DescriptorProto_ExtensionRange::clear_has_start() { +void DescriptorProto_ExtensionRange::clear_has_start() { _has_bits_[0] &= ~0x00000001u; } - void DescriptorProto_ExtensionRange::clear_start() { +void DescriptorProto_ExtensionRange::clear_start() { start_ = 0; clear_has_start(); } @@ -3141,16 +3579,16 @@ void DescriptorProto::InternalSwap(DescriptorProto* other) { } // optional int32 end = 2; - bool DescriptorProto_ExtensionRange::has_end() const { +bool DescriptorProto_ExtensionRange::has_end() const { return (_has_bits_[0] & 0x00000002u) != 0; } - void DescriptorProto_ExtensionRange::set_has_end() { +void DescriptorProto_ExtensionRange::set_has_end() { _has_bits_[0] |= 0x00000002u; } - void DescriptorProto_ExtensionRange::clear_has_end() { +void DescriptorProto_ExtensionRange::clear_has_end() { _has_bits_[0] &= ~0x00000002u; } - void DescriptorProto_ExtensionRange::clear_end() { +void DescriptorProto_ExtensionRange::clear_end() { end_ = 0; clear_has_end(); } @@ -3166,19 +3604,71 @@ void DescriptorProto::InternalSwap(DescriptorProto* other) { // ------------------------------------------------------------------- +// DescriptorProto_ReservedRange + +// optional int32 start = 1; +bool DescriptorProto_ReservedRange::has_start() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +void DescriptorProto_ReservedRange::set_has_start() { + _has_bits_[0] |= 0x00000001u; +} +void DescriptorProto_ReservedRange::clear_has_start() { + _has_bits_[0] &= ~0x00000001u; +} +void DescriptorProto_ReservedRange::clear_start() { + start_ = 0; + clear_has_start(); +} + ::google::protobuf::int32 DescriptorProto_ReservedRange::start() const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ReservedRange.start) + return start_; +} + void DescriptorProto_ReservedRange::set_start(::google::protobuf::int32 value) { + set_has_start(); + start_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ReservedRange.start) +} + +// optional int32 end = 2; +bool DescriptorProto_ReservedRange::has_end() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +void DescriptorProto_ReservedRange::set_has_end() { + _has_bits_[0] |= 0x00000002u; +} +void DescriptorProto_ReservedRange::clear_has_end() { + _has_bits_[0] &= ~0x00000002u; +} +void DescriptorProto_ReservedRange::clear_end() { + end_ = 0; + clear_has_end(); +} + ::google::protobuf::int32 DescriptorProto_ReservedRange::end() const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ReservedRange.end) + return end_; +} + void DescriptorProto_ReservedRange::set_end(::google::protobuf::int32 value) { + set_has_end(); + end_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ReservedRange.end) +} + +// ------------------------------------------------------------------- + // DescriptorProto // optional string name = 1; - bool DescriptorProto::has_name() const { +bool DescriptorProto::has_name() const { return (_has_bits_[0] & 0x00000001u) != 0; } - void DescriptorProto::set_has_name() { +void DescriptorProto::set_has_name() { _has_bits_[0] |= 0x00000001u; } - void DescriptorProto::clear_has_name() { +void DescriptorProto::clear_has_name() { _has_bits_[0] &= ~0x00000001u; } - void DescriptorProto::clear_name() { +void DescriptorProto::clear_name() { name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); clear_has_name(); } @@ -3222,10 +3712,10 @@ void DescriptorProto::InternalSwap(DescriptorProto* other) { } // repeated .google.protobuf.FieldDescriptorProto field = 2; - int DescriptorProto::field_size() const { +int DescriptorProto::field_size() const { return field_.size(); } - void DescriptorProto::clear_field() { +void DescriptorProto::clear_field() { field_.Clear(); } const ::google::protobuf::FieldDescriptorProto& DescriptorProto::field(int index) const { @@ -3252,10 +3742,10 @@ DescriptorProto::mutable_field() { } // repeated .google.protobuf.FieldDescriptorProto extension = 6; - int DescriptorProto::extension_size() const { +int DescriptorProto::extension_size() const { return extension_.size(); } - void DescriptorProto::clear_extension() { +void DescriptorProto::clear_extension() { extension_.Clear(); } const ::google::protobuf::FieldDescriptorProto& DescriptorProto::extension(int index) const { @@ -3282,10 +3772,10 @@ DescriptorProto::mutable_extension() { } // repeated .google.protobuf.DescriptorProto nested_type = 3; - int DescriptorProto::nested_type_size() const { +int DescriptorProto::nested_type_size() const { return nested_type_.size(); } - void DescriptorProto::clear_nested_type() { +void DescriptorProto::clear_nested_type() { nested_type_.Clear(); } const ::google::protobuf::DescriptorProto& DescriptorProto::nested_type(int index) const { @@ -3312,10 +3802,10 @@ DescriptorProto::mutable_nested_type() { } // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; - int DescriptorProto::enum_type_size() const { +int DescriptorProto::enum_type_size() const { return enum_type_.size(); } - void DescriptorProto::clear_enum_type() { +void DescriptorProto::clear_enum_type() { enum_type_.Clear(); } const ::google::protobuf::EnumDescriptorProto& DescriptorProto::enum_type(int index) const { @@ -3342,10 +3832,10 @@ DescriptorProto::mutable_enum_type() { } // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; - int DescriptorProto::extension_range_size() const { +int DescriptorProto::extension_range_size() const { return extension_range_.size(); } - void DescriptorProto::clear_extension_range() { +void DescriptorProto::clear_extension_range() { extension_range_.Clear(); } const ::google::protobuf::DescriptorProto_ExtensionRange& DescriptorProto::extension_range(int index) const { @@ -3372,10 +3862,10 @@ DescriptorProto::mutable_extension_range() { } // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8; - int DescriptorProto::oneof_decl_size() const { +int DescriptorProto::oneof_decl_size() const { return oneof_decl_.size(); } - void DescriptorProto::clear_oneof_decl() { +void DescriptorProto::clear_oneof_decl() { oneof_decl_.Clear(); } const ::google::protobuf::OneofDescriptorProto& DescriptorProto::oneof_decl(int index) const { @@ -3402,16 +3892,16 @@ DescriptorProto::mutable_oneof_decl() { } // optional .google.protobuf.MessageOptions options = 7; - bool DescriptorProto::has_options() const { +bool DescriptorProto::has_options() const { return (_has_bits_[0] & 0x00000080u) != 0; } - void DescriptorProto::set_has_options() { +void DescriptorProto::set_has_options() { _has_bits_[0] |= 0x00000080u; } - void DescriptorProto::clear_has_options() { +void DescriptorProto::clear_has_options() { _has_bits_[0] &= ~0x00000080u; } - void DescriptorProto::clear_options() { +void DescriptorProto::clear_options() { if (options_ != NULL) options_->::google::protobuf::MessageOptions::Clear(); clear_has_options(); } @@ -3444,6 +3934,90 @@ DescriptorProto::mutable_oneof_decl() { // @@protoc_insertion_point(field_set_allocated:google.protobuf.DescriptorProto.options) } +// repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9; +int DescriptorProto::reserved_range_size() const { + return reserved_range_.size(); +} +void DescriptorProto::clear_reserved_range() { + reserved_range_.Clear(); +} + const ::google::protobuf::DescriptorProto_ReservedRange& DescriptorProto::reserved_range(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.reserved_range) + return reserved_range_.Get(index); +} + ::google::protobuf::DescriptorProto_ReservedRange* DescriptorProto::mutable_reserved_range(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.reserved_range) + return reserved_range_.Mutable(index); +} + ::google::protobuf::DescriptorProto_ReservedRange* DescriptorProto::add_reserved_range() { + // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.reserved_range) + return reserved_range_.Add(); +} + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ReservedRange >& +DescriptorProto::reserved_range() const { + // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.reserved_range) + return reserved_range_; +} + ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ReservedRange >* +DescriptorProto::mutable_reserved_range() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.reserved_range) + return &reserved_range_; +} + +// repeated string reserved_name = 10; +int DescriptorProto::reserved_name_size() const { + return reserved_name_.size(); +} +void DescriptorProto::clear_reserved_name() { + reserved_name_.Clear(); +} + const ::std::string& DescriptorProto::reserved_name(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.reserved_name) + return reserved_name_.Get(index); +} + ::std::string* DescriptorProto::mutable_reserved_name(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.reserved_name) + return reserved_name_.Mutable(index); +} + void DescriptorProto::set_reserved_name(int index, const ::std::string& value) { + // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.reserved_name) + reserved_name_.Mutable(index)->assign(value); +} + void DescriptorProto::set_reserved_name(int index, const char* value) { + reserved_name_.Mutable(index)->assign(value); + // @@protoc_insertion_point(field_set_char:google.protobuf.DescriptorProto.reserved_name) +} + 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) +} + ::std::string* DescriptorProto::add_reserved_name() { + return reserved_name_.Add(); +} + void DescriptorProto::add_reserved_name(const ::std::string& value) { + reserved_name_.Add()->assign(value); + // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.reserved_name) +} + void DescriptorProto::add_reserved_name(const char* value) { + reserved_name_.Add()->assign(value); + // @@protoc_insertion_point(field_add_char:google.protobuf.DescriptorProto.reserved_name) +} + 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) +} + const ::google::protobuf::RepeatedPtrField< ::std::string>& +DescriptorProto::reserved_name() const { + // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.reserved_name) + return reserved_name_; +} + ::google::protobuf::RepeatedPtrField< ::std::string>* +DescriptorProto::mutable_reserved_name() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.reserved_name) + return &reserved_name_; +} + #endif // PROTOBUF_INLINE_NOT_IN_HEADERS // =================================================================== @@ -3537,7 +4111,7 @@ const int FieldDescriptorProto::kOptionsFieldNumber; #endif // !_MSC_VER FieldDescriptorProto::FieldDescriptorProto() - : ::google::protobuf::Message() , _internal_metadata_(NULL) { + : ::google::protobuf::Message(), _internal_metadata_(NULL) { SharedCtor(); // @@protoc_insertion_point(constructor:google.protobuf.FieldDescriptorProto) } @@ -3610,7 +4184,7 @@ FieldDescriptorProto* FieldDescriptorProto::New(::google::protobuf::Arena* arena } void FieldDescriptorProto::Clear() { - if (_has_bits_[0 / 32] & 255) { + if (_has_bits_[0 / 32] & 255u) { if (has_name()) { name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); } @@ -4060,9 +4634,9 @@ int FieldDescriptorProto::ByteSize() const { void FieldDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) { if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - const FieldDescriptorProto* source = - ::google::protobuf::internal::dynamic_cast_if_available<const FieldDescriptorProto*>( - &from); + const FieldDescriptorProto* source = + ::google::protobuf::internal::DynamicCastToGenerated<const FieldDescriptorProto>( + &from); if (source == NULL) { ::google::protobuf::internal::ReflectionOps::Merge(from, this); } else { @@ -4163,16 +4737,16 @@ void FieldDescriptorProto::InternalSwap(FieldDescriptorProto* other) { // FieldDescriptorProto // optional string name = 1; - bool FieldDescriptorProto::has_name() const { +bool FieldDescriptorProto::has_name() const { return (_has_bits_[0] & 0x00000001u) != 0; } - void FieldDescriptorProto::set_has_name() { +void FieldDescriptorProto::set_has_name() { _has_bits_[0] |= 0x00000001u; } - void FieldDescriptorProto::clear_has_name() { +void FieldDescriptorProto::clear_has_name() { _has_bits_[0] &= ~0x00000001u; } - void FieldDescriptorProto::clear_name() { +void FieldDescriptorProto::clear_name() { name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); clear_has_name(); } @@ -4216,16 +4790,16 @@ void FieldDescriptorProto::InternalSwap(FieldDescriptorProto* other) { } // optional int32 number = 3; - bool FieldDescriptorProto::has_number() const { +bool FieldDescriptorProto::has_number() const { return (_has_bits_[0] & 0x00000002u) != 0; } - void FieldDescriptorProto::set_has_number() { +void FieldDescriptorProto::set_has_number() { _has_bits_[0] |= 0x00000002u; } - void FieldDescriptorProto::clear_has_number() { +void FieldDescriptorProto::clear_has_number() { _has_bits_[0] &= ~0x00000002u; } - void FieldDescriptorProto::clear_number() { +void FieldDescriptorProto::clear_number() { number_ = 0; clear_has_number(); } @@ -4240,16 +4814,16 @@ void FieldDescriptorProto::InternalSwap(FieldDescriptorProto* other) { } // optional .google.protobuf.FieldDescriptorProto.Label label = 4; - bool FieldDescriptorProto::has_label() const { +bool FieldDescriptorProto::has_label() const { return (_has_bits_[0] & 0x00000004u) != 0; } - void FieldDescriptorProto::set_has_label() { +void FieldDescriptorProto::set_has_label() { _has_bits_[0] |= 0x00000004u; } - void FieldDescriptorProto::clear_has_label() { +void FieldDescriptorProto::clear_has_label() { _has_bits_[0] &= ~0x00000004u; } - void FieldDescriptorProto::clear_label() { +void FieldDescriptorProto::clear_label() { label_ = 1; clear_has_label(); } @@ -4265,16 +4839,16 @@ void FieldDescriptorProto::InternalSwap(FieldDescriptorProto* other) { } // optional .google.protobuf.FieldDescriptorProto.Type type = 5; - bool FieldDescriptorProto::has_type() const { +bool FieldDescriptorProto::has_type() const { return (_has_bits_[0] & 0x00000008u) != 0; } - void FieldDescriptorProto::set_has_type() { +void FieldDescriptorProto::set_has_type() { _has_bits_[0] |= 0x00000008u; } - void FieldDescriptorProto::clear_has_type() { +void FieldDescriptorProto::clear_has_type() { _has_bits_[0] &= ~0x00000008u; } - void FieldDescriptorProto::clear_type() { +void FieldDescriptorProto::clear_type() { type_ = 1; clear_has_type(); } @@ -4290,16 +4864,16 @@ void FieldDescriptorProto::InternalSwap(FieldDescriptorProto* other) { } // optional string type_name = 6; - bool FieldDescriptorProto::has_type_name() const { +bool FieldDescriptorProto::has_type_name() const { return (_has_bits_[0] & 0x00000010u) != 0; } - void FieldDescriptorProto::set_has_type_name() { +void FieldDescriptorProto::set_has_type_name() { _has_bits_[0] |= 0x00000010u; } - void FieldDescriptorProto::clear_has_type_name() { +void FieldDescriptorProto::clear_has_type_name() { _has_bits_[0] &= ~0x00000010u; } - void FieldDescriptorProto::clear_type_name() { +void FieldDescriptorProto::clear_type_name() { type_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); clear_has_type_name(); } @@ -4343,16 +4917,16 @@ void FieldDescriptorProto::InternalSwap(FieldDescriptorProto* other) { } // optional string extendee = 2; - bool FieldDescriptorProto::has_extendee() const { +bool FieldDescriptorProto::has_extendee() const { return (_has_bits_[0] & 0x00000020u) != 0; } - void FieldDescriptorProto::set_has_extendee() { +void FieldDescriptorProto::set_has_extendee() { _has_bits_[0] |= 0x00000020u; } - void FieldDescriptorProto::clear_has_extendee() { +void FieldDescriptorProto::clear_has_extendee() { _has_bits_[0] &= ~0x00000020u; } - void FieldDescriptorProto::clear_extendee() { +void FieldDescriptorProto::clear_extendee() { extendee_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); clear_has_extendee(); } @@ -4396,16 +4970,16 @@ void FieldDescriptorProto::InternalSwap(FieldDescriptorProto* other) { } // optional string default_value = 7; - bool FieldDescriptorProto::has_default_value() const { +bool FieldDescriptorProto::has_default_value() const { return (_has_bits_[0] & 0x00000040u) != 0; } - void FieldDescriptorProto::set_has_default_value() { +void FieldDescriptorProto::set_has_default_value() { _has_bits_[0] |= 0x00000040u; } - void FieldDescriptorProto::clear_has_default_value() { +void FieldDescriptorProto::clear_has_default_value() { _has_bits_[0] &= ~0x00000040u; } - void FieldDescriptorProto::clear_default_value() { +void FieldDescriptorProto::clear_default_value() { default_value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); clear_has_default_value(); } @@ -4449,16 +5023,16 @@ void FieldDescriptorProto::InternalSwap(FieldDescriptorProto* other) { } // optional int32 oneof_index = 9; - bool FieldDescriptorProto::has_oneof_index() const { +bool FieldDescriptorProto::has_oneof_index() const { return (_has_bits_[0] & 0x00000080u) != 0; } - void FieldDescriptorProto::set_has_oneof_index() { +void FieldDescriptorProto::set_has_oneof_index() { _has_bits_[0] |= 0x00000080u; } - void FieldDescriptorProto::clear_has_oneof_index() { +void FieldDescriptorProto::clear_has_oneof_index() { _has_bits_[0] &= ~0x00000080u; } - void FieldDescriptorProto::clear_oneof_index() { +void FieldDescriptorProto::clear_oneof_index() { oneof_index_ = 0; clear_has_oneof_index(); } @@ -4473,16 +5047,16 @@ void FieldDescriptorProto::InternalSwap(FieldDescriptorProto* other) { } // optional .google.protobuf.FieldOptions options = 8; - bool FieldDescriptorProto::has_options() const { +bool FieldDescriptorProto::has_options() const { return (_has_bits_[0] & 0x00000100u) != 0; } - void FieldDescriptorProto::set_has_options() { +void FieldDescriptorProto::set_has_options() { _has_bits_[0] |= 0x00000100u; } - void FieldDescriptorProto::clear_has_options() { +void FieldDescriptorProto::clear_has_options() { _has_bits_[0] &= ~0x00000100u; } - void FieldDescriptorProto::clear_options() { +void FieldDescriptorProto::clear_options() { if (options_ != NULL) options_->::google::protobuf::FieldOptions::Clear(); clear_has_options(); } @@ -4524,7 +5098,7 @@ const int OneofDescriptorProto::kNameFieldNumber; #endif // !_MSC_VER OneofDescriptorProto::OneofDescriptorProto() - : ::google::protobuf::Message() , _internal_metadata_(NULL) { + : ::google::protobuf::Message(), _internal_metadata_(NULL) { SharedCtor(); // @@protoc_insertion_point(constructor:google.protobuf.OneofDescriptorProto) } @@ -4706,9 +5280,9 @@ int OneofDescriptorProto::ByteSize() const { void OneofDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) { if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - const OneofDescriptorProto* source = - ::google::protobuf::internal::dynamic_cast_if_available<const OneofDescriptorProto*>( - &from); + const OneofDescriptorProto* source = + ::google::protobuf::internal::DynamicCastToGenerated<const OneofDescriptorProto>( + &from); if (source == NULL) { ::google::protobuf::internal::ReflectionOps::Merge(from, this); } else { @@ -4769,16 +5343,16 @@ void OneofDescriptorProto::InternalSwap(OneofDescriptorProto* other) { // OneofDescriptorProto // optional string name = 1; - bool OneofDescriptorProto::has_name() const { +bool OneofDescriptorProto::has_name() const { return (_has_bits_[0] & 0x00000001u) != 0; } - void OneofDescriptorProto::set_has_name() { +void OneofDescriptorProto::set_has_name() { _has_bits_[0] |= 0x00000001u; } - void OneofDescriptorProto::clear_has_name() { +void OneofDescriptorProto::clear_has_name() { _has_bits_[0] &= ~0x00000001u; } - void OneofDescriptorProto::clear_name() { +void OneofDescriptorProto::clear_name() { name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); clear_has_name(); } @@ -4832,7 +5406,7 @@ const int EnumDescriptorProto::kOptionsFieldNumber; #endif // !_MSC_VER EnumDescriptorProto::EnumDescriptorProto() - : ::google::protobuf::Message() , _internal_metadata_(NULL) { + : ::google::protobuf::Message(), _internal_metadata_(NULL) { SharedCtor(); // @@protoc_insertion_point(constructor:google.protobuf.EnumDescriptorProto) } @@ -4895,7 +5469,7 @@ EnumDescriptorProto* EnumDescriptorProto::New(::google::protobuf::Arena* arena) } void EnumDescriptorProto::Clear() { - if (_has_bits_[0 / 32] & 5) { + if (_has_bits_[0 / 32] & 5u) { if (has_name()) { name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); } @@ -4940,12 +5514,15 @@ bool EnumDescriptorProto::MergePartialFromCodedStream( case 2: { if (tag == 18) { parse_value: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + DO_(input->IncrementRecursionDepth()); + parse_loop_value: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( input, add_value())); } else { goto handle_unusual; } - if (input->ExpectTag(18)) goto parse_value; + if (input->ExpectTag(18)) goto parse_loop_value; + input->UnsafeDecrementRecursionDepth(); if (input->ExpectTag(26)) goto parse_options; break; } @@ -5093,9 +5670,9 @@ int EnumDescriptorProto::ByteSize() const { void EnumDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) { if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - const EnumDescriptorProto* source = - ::google::protobuf::internal::dynamic_cast_if_available<const EnumDescriptorProto*>( - &from); + const EnumDescriptorProto* source = + ::google::protobuf::internal::DynamicCastToGenerated<const EnumDescriptorProto>( + &from); if (source == NULL) { ::google::protobuf::internal::ReflectionOps::Merge(from, this); } else { @@ -5166,16 +5743,16 @@ void EnumDescriptorProto::InternalSwap(EnumDescriptorProto* other) { // EnumDescriptorProto // optional string name = 1; - bool EnumDescriptorProto::has_name() const { +bool EnumDescriptorProto::has_name() const { return (_has_bits_[0] & 0x00000001u) != 0; } - void EnumDescriptorProto::set_has_name() { +void EnumDescriptorProto::set_has_name() { _has_bits_[0] |= 0x00000001u; } - void EnumDescriptorProto::clear_has_name() { +void EnumDescriptorProto::clear_has_name() { _has_bits_[0] &= ~0x00000001u; } - void EnumDescriptorProto::clear_name() { +void EnumDescriptorProto::clear_name() { name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); clear_has_name(); } @@ -5219,10 +5796,10 @@ void EnumDescriptorProto::InternalSwap(EnumDescriptorProto* other) { } // repeated .google.protobuf.EnumValueDescriptorProto value = 2; - int EnumDescriptorProto::value_size() const { +int EnumDescriptorProto::value_size() const { return value_.size(); } - void EnumDescriptorProto::clear_value() { +void EnumDescriptorProto::clear_value() { value_.Clear(); } const ::google::protobuf::EnumValueDescriptorProto& EnumDescriptorProto::value(int index) const { @@ -5249,16 +5826,16 @@ EnumDescriptorProto::mutable_value() { } // optional .google.protobuf.EnumOptions options = 3; - bool EnumDescriptorProto::has_options() const { +bool EnumDescriptorProto::has_options() const { return (_has_bits_[0] & 0x00000004u) != 0; } - void EnumDescriptorProto::set_has_options() { +void EnumDescriptorProto::set_has_options() { _has_bits_[0] |= 0x00000004u; } - void EnumDescriptorProto::clear_has_options() { +void EnumDescriptorProto::clear_has_options() { _has_bits_[0] &= ~0x00000004u; } - void EnumDescriptorProto::clear_options() { +void EnumDescriptorProto::clear_options() { if (options_ != NULL) options_->::google::protobuf::EnumOptions::Clear(); clear_has_options(); } @@ -5302,7 +5879,7 @@ const int EnumValueDescriptorProto::kOptionsFieldNumber; #endif // !_MSC_VER EnumValueDescriptorProto::EnumValueDescriptorProto() - : ::google::protobuf::Message() , _internal_metadata_(NULL) { + : ::google::protobuf::Message(), _internal_metadata_(NULL) { SharedCtor(); // @@protoc_insertion_point(constructor:google.protobuf.EnumValueDescriptorProto) } @@ -5366,7 +5943,7 @@ EnumValueDescriptorProto* EnumValueDescriptorProto::New(::google::protobuf::Aren } void EnumValueDescriptorProto::Clear() { - if (_has_bits_[0 / 32] & 7) { + if (_has_bits_[0 / 32] & 7u) { if (has_name()) { name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); } @@ -5561,9 +6138,9 @@ int EnumValueDescriptorProto::ByteSize() const { void EnumValueDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) { if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - const EnumValueDescriptorProto* source = - ::google::protobuf::internal::dynamic_cast_if_available<const EnumValueDescriptorProto*>( - &from); + const EnumValueDescriptorProto* source = + ::google::protobuf::internal::DynamicCastToGenerated<const EnumValueDescriptorProto>( + &from); if (source == NULL) { ::google::protobuf::internal::ReflectionOps::Merge(from, this); } else { @@ -5635,16 +6212,16 @@ void EnumValueDescriptorProto::InternalSwap(EnumValueDescriptorProto* other) { // EnumValueDescriptorProto // optional string name = 1; - bool EnumValueDescriptorProto::has_name() const { +bool EnumValueDescriptorProto::has_name() const { return (_has_bits_[0] & 0x00000001u) != 0; } - void EnumValueDescriptorProto::set_has_name() { +void EnumValueDescriptorProto::set_has_name() { _has_bits_[0] |= 0x00000001u; } - void EnumValueDescriptorProto::clear_has_name() { +void EnumValueDescriptorProto::clear_has_name() { _has_bits_[0] &= ~0x00000001u; } - void EnumValueDescriptorProto::clear_name() { +void EnumValueDescriptorProto::clear_name() { name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); clear_has_name(); } @@ -5688,16 +6265,16 @@ void EnumValueDescriptorProto::InternalSwap(EnumValueDescriptorProto* other) { } // optional int32 number = 2; - bool EnumValueDescriptorProto::has_number() const { +bool EnumValueDescriptorProto::has_number() const { return (_has_bits_[0] & 0x00000002u) != 0; } - void EnumValueDescriptorProto::set_has_number() { +void EnumValueDescriptorProto::set_has_number() { _has_bits_[0] |= 0x00000002u; } - void EnumValueDescriptorProto::clear_has_number() { +void EnumValueDescriptorProto::clear_has_number() { _has_bits_[0] &= ~0x00000002u; } - void EnumValueDescriptorProto::clear_number() { +void EnumValueDescriptorProto::clear_number() { number_ = 0; clear_has_number(); } @@ -5712,16 +6289,16 @@ void EnumValueDescriptorProto::InternalSwap(EnumValueDescriptorProto* other) { } // optional .google.protobuf.EnumValueOptions options = 3; - bool EnumValueDescriptorProto::has_options() const { +bool EnumValueDescriptorProto::has_options() const { return (_has_bits_[0] & 0x00000004u) != 0; } - void EnumValueDescriptorProto::set_has_options() { +void EnumValueDescriptorProto::set_has_options() { _has_bits_[0] |= 0x00000004u; } - void EnumValueDescriptorProto::clear_has_options() { +void EnumValueDescriptorProto::clear_has_options() { _has_bits_[0] &= ~0x00000004u; } - void EnumValueDescriptorProto::clear_options() { +void EnumValueDescriptorProto::clear_options() { if (options_ != NULL) options_->::google::protobuf::EnumValueOptions::Clear(); clear_has_options(); } @@ -5765,7 +6342,7 @@ const int ServiceDescriptorProto::kOptionsFieldNumber; #endif // !_MSC_VER ServiceDescriptorProto::ServiceDescriptorProto() - : ::google::protobuf::Message() , _internal_metadata_(NULL) { + : ::google::protobuf::Message(), _internal_metadata_(NULL) { SharedCtor(); // @@protoc_insertion_point(constructor:google.protobuf.ServiceDescriptorProto) } @@ -5828,7 +6405,7 @@ ServiceDescriptorProto* ServiceDescriptorProto::New(::google::protobuf::Arena* a } void ServiceDescriptorProto::Clear() { - if (_has_bits_[0 / 32] & 5) { + if (_has_bits_[0 / 32] & 5u) { if (has_name()) { name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); } @@ -5873,12 +6450,15 @@ bool ServiceDescriptorProto::MergePartialFromCodedStream( case 2: { if (tag == 18) { parse_method: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + DO_(input->IncrementRecursionDepth()); + parse_loop_method: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( input, add_method())); } else { goto handle_unusual; } - if (input->ExpectTag(18)) goto parse_method; + if (input->ExpectTag(18)) goto parse_loop_method; + input->UnsafeDecrementRecursionDepth(); if (input->ExpectTag(26)) goto parse_options; break; } @@ -6026,9 +6606,9 @@ int ServiceDescriptorProto::ByteSize() const { void ServiceDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) { if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - const ServiceDescriptorProto* source = - ::google::protobuf::internal::dynamic_cast_if_available<const ServiceDescriptorProto*>( - &from); + const ServiceDescriptorProto* source = + ::google::protobuf::internal::DynamicCastToGenerated<const ServiceDescriptorProto>( + &from); if (source == NULL) { ::google::protobuf::internal::ReflectionOps::Merge(from, this); } else { @@ -6099,16 +6679,16 @@ void ServiceDescriptorProto::InternalSwap(ServiceDescriptorProto* other) { // ServiceDescriptorProto // optional string name = 1; - bool ServiceDescriptorProto::has_name() const { +bool ServiceDescriptorProto::has_name() const { return (_has_bits_[0] & 0x00000001u) != 0; } - void ServiceDescriptorProto::set_has_name() { +void ServiceDescriptorProto::set_has_name() { _has_bits_[0] |= 0x00000001u; } - void ServiceDescriptorProto::clear_has_name() { +void ServiceDescriptorProto::clear_has_name() { _has_bits_[0] &= ~0x00000001u; } - void ServiceDescriptorProto::clear_name() { +void ServiceDescriptorProto::clear_name() { name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); clear_has_name(); } @@ -6152,10 +6732,10 @@ void ServiceDescriptorProto::InternalSwap(ServiceDescriptorProto* other) { } // repeated .google.protobuf.MethodDescriptorProto method = 2; - int ServiceDescriptorProto::method_size() const { +int ServiceDescriptorProto::method_size() const { return method_.size(); } - void ServiceDescriptorProto::clear_method() { +void ServiceDescriptorProto::clear_method() { method_.Clear(); } const ::google::protobuf::MethodDescriptorProto& ServiceDescriptorProto::method(int index) const { @@ -6182,16 +6762,16 @@ ServiceDescriptorProto::mutable_method() { } // optional .google.protobuf.ServiceOptions options = 3; - bool ServiceDescriptorProto::has_options() const { +bool ServiceDescriptorProto::has_options() const { return (_has_bits_[0] & 0x00000004u) != 0; } - void ServiceDescriptorProto::set_has_options() { +void ServiceDescriptorProto::set_has_options() { _has_bits_[0] |= 0x00000004u; } - void ServiceDescriptorProto::clear_has_options() { +void ServiceDescriptorProto::clear_has_options() { _has_bits_[0] &= ~0x00000004u; } - void ServiceDescriptorProto::clear_options() { +void ServiceDescriptorProto::clear_options() { if (options_ != NULL) options_->::google::protobuf::ServiceOptions::Clear(); clear_has_options(); } @@ -6238,7 +6818,7 @@ const int MethodDescriptorProto::kServerStreamingFieldNumber; #endif // !_MSC_VER MethodDescriptorProto::MethodDescriptorProto() - : ::google::protobuf::Message() , _internal_metadata_(NULL) { + : ::google::protobuf::Message(), _internal_metadata_(NULL) { SharedCtor(); // @@protoc_insertion_point(constructor:google.protobuf.MethodDescriptorProto) } @@ -6315,7 +6895,7 @@ void MethodDescriptorProto::Clear() { ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\ } while (0) - if (_has_bits_[0 / 32] & 63) { + if (_has_bits_[0 / 32] & 63u) { ZR_(client_streaming_, server_streaming_); if (has_name()) { name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); @@ -6638,9 +7218,9 @@ int MethodDescriptorProto::ByteSize() const { void MethodDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) { if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - const MethodDescriptorProto* source = - ::google::protobuf::internal::dynamic_cast_if_available<const MethodDescriptorProto*>( - &from); + const MethodDescriptorProto* source = + ::google::protobuf::internal::DynamicCastToGenerated<const MethodDescriptorProto>( + &from); if (source == NULL) { ::google::protobuf::internal::ReflectionOps::Merge(from, this); } else { @@ -6726,16 +7306,16 @@ void MethodDescriptorProto::InternalSwap(MethodDescriptorProto* other) { // MethodDescriptorProto // optional string name = 1; - bool MethodDescriptorProto::has_name() const { +bool MethodDescriptorProto::has_name() const { return (_has_bits_[0] & 0x00000001u) != 0; } - void MethodDescriptorProto::set_has_name() { +void MethodDescriptorProto::set_has_name() { _has_bits_[0] |= 0x00000001u; } - void MethodDescriptorProto::clear_has_name() { +void MethodDescriptorProto::clear_has_name() { _has_bits_[0] &= ~0x00000001u; } - void MethodDescriptorProto::clear_name() { +void MethodDescriptorProto::clear_name() { name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); clear_has_name(); } @@ -6779,16 +7359,16 @@ void MethodDescriptorProto::InternalSwap(MethodDescriptorProto* other) { } // optional string input_type = 2; - bool MethodDescriptorProto::has_input_type() const { +bool MethodDescriptorProto::has_input_type() const { return (_has_bits_[0] & 0x00000002u) != 0; } - void MethodDescriptorProto::set_has_input_type() { +void MethodDescriptorProto::set_has_input_type() { _has_bits_[0] |= 0x00000002u; } - void MethodDescriptorProto::clear_has_input_type() { +void MethodDescriptorProto::clear_has_input_type() { _has_bits_[0] &= ~0x00000002u; } - void MethodDescriptorProto::clear_input_type() { +void MethodDescriptorProto::clear_input_type() { input_type_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); clear_has_input_type(); } @@ -6832,16 +7412,16 @@ void MethodDescriptorProto::InternalSwap(MethodDescriptorProto* other) { } // optional string output_type = 3; - bool MethodDescriptorProto::has_output_type() const { +bool MethodDescriptorProto::has_output_type() const { return (_has_bits_[0] & 0x00000004u) != 0; } - void MethodDescriptorProto::set_has_output_type() { +void MethodDescriptorProto::set_has_output_type() { _has_bits_[0] |= 0x00000004u; } - void MethodDescriptorProto::clear_has_output_type() { +void MethodDescriptorProto::clear_has_output_type() { _has_bits_[0] &= ~0x00000004u; } - void MethodDescriptorProto::clear_output_type() { +void MethodDescriptorProto::clear_output_type() { output_type_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); clear_has_output_type(); } @@ -6885,16 +7465,16 @@ void MethodDescriptorProto::InternalSwap(MethodDescriptorProto* other) { } // optional .google.protobuf.MethodOptions options = 4; - bool MethodDescriptorProto::has_options() const { +bool MethodDescriptorProto::has_options() const { return (_has_bits_[0] & 0x00000008u) != 0; } - void MethodDescriptorProto::set_has_options() { +void MethodDescriptorProto::set_has_options() { _has_bits_[0] |= 0x00000008u; } - void MethodDescriptorProto::clear_has_options() { +void MethodDescriptorProto::clear_has_options() { _has_bits_[0] &= ~0x00000008u; } - void MethodDescriptorProto::clear_options() { +void MethodDescriptorProto::clear_options() { if (options_ != NULL) options_->::google::protobuf::MethodOptions::Clear(); clear_has_options(); } @@ -6928,16 +7508,16 @@ void MethodDescriptorProto::InternalSwap(MethodDescriptorProto* other) { } // optional bool client_streaming = 5 [default = false]; - bool MethodDescriptorProto::has_client_streaming() const { +bool MethodDescriptorProto::has_client_streaming() const { return (_has_bits_[0] & 0x00000010u) != 0; } - void MethodDescriptorProto::set_has_client_streaming() { +void MethodDescriptorProto::set_has_client_streaming() { _has_bits_[0] |= 0x00000010u; } - void MethodDescriptorProto::clear_has_client_streaming() { +void MethodDescriptorProto::clear_has_client_streaming() { _has_bits_[0] &= ~0x00000010u; } - void MethodDescriptorProto::clear_client_streaming() { +void MethodDescriptorProto::clear_client_streaming() { client_streaming_ = false; clear_has_client_streaming(); } @@ -6952,16 +7532,16 @@ void MethodDescriptorProto::InternalSwap(MethodDescriptorProto* other) { } // optional bool server_streaming = 6 [default = false]; - bool MethodDescriptorProto::has_server_streaming() const { +bool MethodDescriptorProto::has_server_streaming() const { return (_has_bits_[0] & 0x00000020u) != 0; } - void MethodDescriptorProto::set_has_server_streaming() { +void MethodDescriptorProto::set_has_server_streaming() { _has_bits_[0] |= 0x00000020u; } - void MethodDescriptorProto::clear_has_server_streaming() { +void MethodDescriptorProto::clear_has_server_streaming() { _has_bits_[0] &= ~0x00000020u; } - void MethodDescriptorProto::clear_server_streaming() { +void MethodDescriptorProto::clear_server_streaming() { server_streaming_ = false; clear_has_server_streaming(); } @@ -7016,11 +7596,12 @@ const int FileOptions::kPyGenericServicesFieldNumber; const int FileOptions::kDeprecatedFieldNumber; const int FileOptions::kCcEnableArenasFieldNumber; const int FileOptions::kObjcClassPrefixFieldNumber; +const int FileOptions::kCsharpNamespaceFieldNumber; const int FileOptions::kUninterpretedOptionFieldNumber; #endif // !_MSC_VER FileOptions::FileOptions() - : ::google::protobuf::Message() , _internal_metadata_(NULL) { + : ::google::protobuf::Message(), _internal_metadata_(NULL) { SharedCtor(); // @@protoc_insertion_point(constructor:google.protobuf.FileOptions) } @@ -7052,6 +7633,7 @@ void FileOptions::SharedCtor() { deprecated_ = false; cc_enable_arenas_ = false; objc_class_prefix_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + csharp_namespace_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); ::memset(_has_bits_, 0, sizeof(_has_bits_)); } @@ -7065,6 +7647,7 @@ void FileOptions::SharedDtor() { java_outer_classname_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); go_package_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); objc_class_prefix_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + csharp_namespace_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); if (this != default_instance_) { } } @@ -7104,7 +7687,7 @@ void FileOptions::Clear() { ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\ } while (0) - if (_has_bits_[0 / 32] & 255) { + if (_has_bits_[0 / 32] & 255u) { ZR_(java_multiple_files_, cc_generic_services_); if (has_java_package()) { java_package_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); @@ -7117,11 +7700,14 @@ void FileOptions::Clear() { go_package_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); } } - if (_has_bits_[8 / 32] & 7936) { + if (_has_bits_[8 / 32] & 16128u) { ZR_(java_generic_services_, cc_enable_arenas_); if (has_objc_class_prefix()) { objc_class_prefix_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); } + if (has_csharp_namespace()) { + csharp_namespace_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } } #undef ZR_HELPER_ @@ -7347,6 +7933,23 @@ bool FileOptions::MergePartialFromCodedStream( } else { goto handle_unusual; } + if (input->ExpectTag(298)) goto parse_csharp_namespace; + break; + } + + // optional string csharp_namespace = 37; + case 37: { + if (tag == 298) { + parse_csharp_namespace: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_csharp_namespace())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->csharp_namespace().data(), this->csharp_namespace().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "google.protobuf.FileOptions.csharp_namespace"); + } else { + goto handle_unusual; + } if (input->ExpectTag(7994)) goto parse_uninterpreted_option; break; } @@ -7355,12 +7958,15 @@ bool FileOptions::MergePartialFromCodedStream( case 999: { if (tag == 7994) { parse_uninterpreted_option: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + DO_(input->IncrementRecursionDepth()); + parse_loop_uninterpreted_option: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( input, add_uninterpreted_option())); } else { goto handle_unusual; } - if (input->ExpectTag(7994)) goto parse_uninterpreted_option; + if (input->ExpectTag(7994)) goto parse_loop_uninterpreted_option; + input->UnsafeDecrementRecursionDepth(); if (input->ExpectAtEnd()) goto success; break; } @@ -7481,6 +8087,16 @@ void FileOptions::SerializeWithCachedSizes( 36, this->objc_class_prefix(), output); } + // optional string csharp_namespace = 37; + if (has_csharp_namespace()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->csharp_namespace().data(), this->csharp_namespace().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.FileOptions.csharp_namespace"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 37, this->csharp_namespace(), output); + } + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( @@ -7591,6 +8207,17 @@ void FileOptions::SerializeWithCachedSizes( 36, this->objc_class_prefix(), target); } + // optional string csharp_namespace = 37; + if (has_csharp_namespace()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->csharp_namespace().data(), this->csharp_namespace().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.FileOptions.csharp_namespace"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 37, this->csharp_namespace(), target); + } + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: @@ -7662,7 +8289,7 @@ int FileOptions::ByteSize() const { } } - if (_has_bits_[8 / 32] & 7936) { + if (_has_bits_[8 / 32] & 16128) { // optional bool java_generic_services = 17 [default = false]; if (has_java_generic_services()) { total_size += 2 + 1; @@ -7690,6 +8317,13 @@ int FileOptions::ByteSize() const { this->objc_class_prefix()); } + // optional string csharp_namespace = 37; + if (has_csharp_namespace()) { + total_size += 2 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->csharp_namespace()); + } + } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; total_size += 2 * this->uninterpreted_option_size(); @@ -7714,9 +8348,9 @@ int FileOptions::ByteSize() const { void FileOptions::MergeFrom(const ::google::protobuf::Message& from) { if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - const FileOptions* source = - ::google::protobuf::internal::dynamic_cast_if_available<const FileOptions*>( - &from); + const FileOptions* source = + ::google::protobuf::internal::DynamicCastToGenerated<const FileOptions>( + &from); if (source == NULL) { ::google::protobuf::internal::ReflectionOps::Merge(from, this); } else { @@ -7773,6 +8407,10 @@ void FileOptions::MergeFrom(const FileOptions& from) { set_has_objc_class_prefix(); objc_class_prefix_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.objc_class_prefix_); } + if (from.has_csharp_namespace()) { + set_has_csharp_namespace(); + csharp_namespace_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.csharp_namespace_); + } } _extensions_.MergeFrom(from._extensions_); if (from._internal_metadata_.have_unknown_fields()) { @@ -7817,6 +8455,7 @@ void FileOptions::InternalSwap(FileOptions* other) { std::swap(deprecated_, other->deprecated_); std::swap(cc_enable_arenas_, other->cc_enable_arenas_); objc_class_prefix_.Swap(&other->objc_class_prefix_); + csharp_namespace_.Swap(&other->csharp_namespace_); uninterpreted_option_.UnsafeArenaSwap(&other->uninterpreted_option_); std::swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); @@ -7836,16 +8475,16 @@ void FileOptions::InternalSwap(FileOptions* other) { // FileOptions // optional string java_package = 1; - bool FileOptions::has_java_package() const { +bool FileOptions::has_java_package() const { return (_has_bits_[0] & 0x00000001u) != 0; } - void FileOptions::set_has_java_package() { +void FileOptions::set_has_java_package() { _has_bits_[0] |= 0x00000001u; } - void FileOptions::clear_has_java_package() { +void FileOptions::clear_has_java_package() { _has_bits_[0] &= ~0x00000001u; } - void FileOptions::clear_java_package() { +void FileOptions::clear_java_package() { java_package_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); clear_has_java_package(); } @@ -7889,16 +8528,16 @@ void FileOptions::InternalSwap(FileOptions* other) { } // optional string java_outer_classname = 8; - bool FileOptions::has_java_outer_classname() const { +bool FileOptions::has_java_outer_classname() const { return (_has_bits_[0] & 0x00000002u) != 0; } - void FileOptions::set_has_java_outer_classname() { +void FileOptions::set_has_java_outer_classname() { _has_bits_[0] |= 0x00000002u; } - void FileOptions::clear_has_java_outer_classname() { +void FileOptions::clear_has_java_outer_classname() { _has_bits_[0] &= ~0x00000002u; } - void FileOptions::clear_java_outer_classname() { +void FileOptions::clear_java_outer_classname() { java_outer_classname_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); clear_has_java_outer_classname(); } @@ -7942,16 +8581,16 @@ void FileOptions::InternalSwap(FileOptions* other) { } // optional bool java_multiple_files = 10 [default = false]; - bool FileOptions::has_java_multiple_files() const { +bool FileOptions::has_java_multiple_files() const { return (_has_bits_[0] & 0x00000004u) != 0; } - void FileOptions::set_has_java_multiple_files() { +void FileOptions::set_has_java_multiple_files() { _has_bits_[0] |= 0x00000004u; } - void FileOptions::clear_has_java_multiple_files() { +void FileOptions::clear_has_java_multiple_files() { _has_bits_[0] &= ~0x00000004u; } - void FileOptions::clear_java_multiple_files() { +void FileOptions::clear_java_multiple_files() { java_multiple_files_ = false; clear_has_java_multiple_files(); } @@ -7966,16 +8605,16 @@ void FileOptions::InternalSwap(FileOptions* other) { } // optional bool java_generate_equals_and_hash = 20 [default = false]; - bool FileOptions::has_java_generate_equals_and_hash() const { +bool FileOptions::has_java_generate_equals_and_hash() const { return (_has_bits_[0] & 0x00000008u) != 0; } - void FileOptions::set_has_java_generate_equals_and_hash() { +void FileOptions::set_has_java_generate_equals_and_hash() { _has_bits_[0] |= 0x00000008u; } - void FileOptions::clear_has_java_generate_equals_and_hash() { +void FileOptions::clear_has_java_generate_equals_and_hash() { _has_bits_[0] &= ~0x00000008u; } - void FileOptions::clear_java_generate_equals_and_hash() { +void FileOptions::clear_java_generate_equals_and_hash() { java_generate_equals_and_hash_ = false; clear_has_java_generate_equals_and_hash(); } @@ -7990,16 +8629,16 @@ void FileOptions::InternalSwap(FileOptions* other) { } // optional bool java_string_check_utf8 = 27 [default = false]; - bool FileOptions::has_java_string_check_utf8() const { +bool FileOptions::has_java_string_check_utf8() const { return (_has_bits_[0] & 0x00000010u) != 0; } - void FileOptions::set_has_java_string_check_utf8() { +void FileOptions::set_has_java_string_check_utf8() { _has_bits_[0] |= 0x00000010u; } - void FileOptions::clear_has_java_string_check_utf8() { +void FileOptions::clear_has_java_string_check_utf8() { _has_bits_[0] &= ~0x00000010u; } - void FileOptions::clear_java_string_check_utf8() { +void FileOptions::clear_java_string_check_utf8() { java_string_check_utf8_ = false; clear_has_java_string_check_utf8(); } @@ -8014,16 +8653,16 @@ void FileOptions::InternalSwap(FileOptions* other) { } // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; - bool FileOptions::has_optimize_for() const { +bool FileOptions::has_optimize_for() const { return (_has_bits_[0] & 0x00000020u) != 0; } - void FileOptions::set_has_optimize_for() { +void FileOptions::set_has_optimize_for() { _has_bits_[0] |= 0x00000020u; } - void FileOptions::clear_has_optimize_for() { +void FileOptions::clear_has_optimize_for() { _has_bits_[0] &= ~0x00000020u; } - void FileOptions::clear_optimize_for() { +void FileOptions::clear_optimize_for() { optimize_for_ = 1; clear_has_optimize_for(); } @@ -8039,16 +8678,16 @@ void FileOptions::InternalSwap(FileOptions* other) { } // optional string go_package = 11; - bool FileOptions::has_go_package() const { +bool FileOptions::has_go_package() const { return (_has_bits_[0] & 0x00000040u) != 0; } - void FileOptions::set_has_go_package() { +void FileOptions::set_has_go_package() { _has_bits_[0] |= 0x00000040u; } - void FileOptions::clear_has_go_package() { +void FileOptions::clear_has_go_package() { _has_bits_[0] &= ~0x00000040u; } - void FileOptions::clear_go_package() { +void FileOptions::clear_go_package() { go_package_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); clear_has_go_package(); } @@ -8092,16 +8731,16 @@ void FileOptions::InternalSwap(FileOptions* other) { } // optional bool cc_generic_services = 16 [default = false]; - bool FileOptions::has_cc_generic_services() const { +bool FileOptions::has_cc_generic_services() const { return (_has_bits_[0] & 0x00000080u) != 0; } - void FileOptions::set_has_cc_generic_services() { +void FileOptions::set_has_cc_generic_services() { _has_bits_[0] |= 0x00000080u; } - void FileOptions::clear_has_cc_generic_services() { +void FileOptions::clear_has_cc_generic_services() { _has_bits_[0] &= ~0x00000080u; } - void FileOptions::clear_cc_generic_services() { +void FileOptions::clear_cc_generic_services() { cc_generic_services_ = false; clear_has_cc_generic_services(); } @@ -8116,16 +8755,16 @@ void FileOptions::InternalSwap(FileOptions* other) { } // optional bool java_generic_services = 17 [default = false]; - bool FileOptions::has_java_generic_services() const { +bool FileOptions::has_java_generic_services() const { return (_has_bits_[0] & 0x00000100u) != 0; } - void FileOptions::set_has_java_generic_services() { +void FileOptions::set_has_java_generic_services() { _has_bits_[0] |= 0x00000100u; } - void FileOptions::clear_has_java_generic_services() { +void FileOptions::clear_has_java_generic_services() { _has_bits_[0] &= ~0x00000100u; } - void FileOptions::clear_java_generic_services() { +void FileOptions::clear_java_generic_services() { java_generic_services_ = false; clear_has_java_generic_services(); } @@ -8140,16 +8779,16 @@ void FileOptions::InternalSwap(FileOptions* other) { } // optional bool py_generic_services = 18 [default = false]; - bool FileOptions::has_py_generic_services() const { +bool FileOptions::has_py_generic_services() const { return (_has_bits_[0] & 0x00000200u) != 0; } - void FileOptions::set_has_py_generic_services() { +void FileOptions::set_has_py_generic_services() { _has_bits_[0] |= 0x00000200u; } - void FileOptions::clear_has_py_generic_services() { +void FileOptions::clear_has_py_generic_services() { _has_bits_[0] &= ~0x00000200u; } - void FileOptions::clear_py_generic_services() { +void FileOptions::clear_py_generic_services() { py_generic_services_ = false; clear_has_py_generic_services(); } @@ -8164,16 +8803,16 @@ void FileOptions::InternalSwap(FileOptions* other) { } // optional bool deprecated = 23 [default = false]; - bool FileOptions::has_deprecated() const { +bool FileOptions::has_deprecated() const { return (_has_bits_[0] & 0x00000400u) != 0; } - void FileOptions::set_has_deprecated() { +void FileOptions::set_has_deprecated() { _has_bits_[0] |= 0x00000400u; } - void FileOptions::clear_has_deprecated() { +void FileOptions::clear_has_deprecated() { _has_bits_[0] &= ~0x00000400u; } - void FileOptions::clear_deprecated() { +void FileOptions::clear_deprecated() { deprecated_ = false; clear_has_deprecated(); } @@ -8188,16 +8827,16 @@ void FileOptions::InternalSwap(FileOptions* other) { } // optional bool cc_enable_arenas = 31 [default = false]; - bool FileOptions::has_cc_enable_arenas() const { +bool FileOptions::has_cc_enable_arenas() const { return (_has_bits_[0] & 0x00000800u) != 0; } - void FileOptions::set_has_cc_enable_arenas() { +void FileOptions::set_has_cc_enable_arenas() { _has_bits_[0] |= 0x00000800u; } - void FileOptions::clear_has_cc_enable_arenas() { +void FileOptions::clear_has_cc_enable_arenas() { _has_bits_[0] &= ~0x00000800u; } - void FileOptions::clear_cc_enable_arenas() { +void FileOptions::clear_cc_enable_arenas() { cc_enable_arenas_ = false; clear_has_cc_enable_arenas(); } @@ -8212,16 +8851,16 @@ void FileOptions::InternalSwap(FileOptions* other) { } // optional string objc_class_prefix = 36; - bool FileOptions::has_objc_class_prefix() const { +bool FileOptions::has_objc_class_prefix() const { return (_has_bits_[0] & 0x00001000u) != 0; } - void FileOptions::set_has_objc_class_prefix() { +void FileOptions::set_has_objc_class_prefix() { _has_bits_[0] |= 0x00001000u; } - void FileOptions::clear_has_objc_class_prefix() { +void FileOptions::clear_has_objc_class_prefix() { _has_bits_[0] &= ~0x00001000u; } - void FileOptions::clear_objc_class_prefix() { +void FileOptions::clear_objc_class_prefix() { objc_class_prefix_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); clear_has_objc_class_prefix(); } @@ -8264,11 +8903,64 @@ void FileOptions::InternalSwap(FileOptions* other) { // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.objc_class_prefix) } +// optional string csharp_namespace = 37; +bool FileOptions::has_csharp_namespace() const { + return (_has_bits_[0] & 0x00002000u) != 0; +} +void FileOptions::set_has_csharp_namespace() { + _has_bits_[0] |= 0x00002000u; +} +void FileOptions::clear_has_csharp_namespace() { + _has_bits_[0] &= ~0x00002000u; +} +void FileOptions::clear_csharp_namespace() { + csharp_namespace_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_csharp_namespace(); +} + const ::std::string& FileOptions::csharp_namespace() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.csharp_namespace) + return csharp_namespace_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void FileOptions::set_csharp_namespace(const ::std::string& value) { + set_has_csharp_namespace(); + csharp_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.csharp_namespace) +} + void FileOptions::set_csharp_namespace(const char* value) { + set_has_csharp_namespace(); + csharp_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.csharp_namespace) +} + void FileOptions::set_csharp_namespace(const char* value, size_t size) { + set_has_csharp_namespace(); + csharp_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.csharp_namespace) +} + ::std::string* FileOptions::mutable_csharp_namespace() { + set_has_csharp_namespace(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.csharp_namespace) + return csharp_namespace_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* FileOptions::release_csharp_namespace() { + clear_has_csharp_namespace(); + return csharp_namespace_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void FileOptions::set_allocated_csharp_namespace(::std::string* csharp_namespace) { + if (csharp_namespace != NULL) { + set_has_csharp_namespace(); + } else { + clear_has_csharp_namespace(); + } + csharp_namespace_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), csharp_namespace); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.csharp_namespace) +} + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - int FileOptions::uninterpreted_option_size() const { +int FileOptions::uninterpreted_option_size() const { return uninterpreted_option_.size(); } - void FileOptions::clear_uninterpreted_option() { +void FileOptions::clear_uninterpreted_option() { uninterpreted_option_.Clear(); } const ::google::protobuf::UninterpretedOption& FileOptions::uninterpreted_option(int index) const { @@ -8307,7 +8999,7 @@ const int MessageOptions::kUninterpretedOptionFieldNumber; #endif // !_MSC_VER MessageOptions::MessageOptions() - : ::google::protobuf::Message() , _internal_metadata_(NULL) { + : ::google::protobuf::Message(), _internal_metadata_(NULL) { SharedCtor(); // @@protoc_insertion_point(constructor:google.protobuf.MessageOptions) } @@ -8462,12 +9154,15 @@ bool MessageOptions::MergePartialFromCodedStream( case 999: { if (tag == 7994) { parse_uninterpreted_option: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + DO_(input->IncrementRecursionDepth()); + parse_loop_uninterpreted_option: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( input, add_uninterpreted_option())); } else { goto handle_unusual; } - if (input->ExpectTag(7994)) goto parse_uninterpreted_option; + if (input->ExpectTag(7994)) goto parse_loop_uninterpreted_option; + input->UnsafeDecrementRecursionDepth(); if (input->ExpectAtEnd()) goto success; break; } @@ -8629,9 +9324,9 @@ int MessageOptions::ByteSize() const { void MessageOptions::MergeFrom(const ::google::protobuf::Message& from) { if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - const MessageOptions* source = - ::google::protobuf::internal::dynamic_cast_if_available<const MessageOptions*>( - &from); + const MessageOptions* source = + ::google::protobuf::internal::DynamicCastToGenerated<const MessageOptions>( + &from); if (source == NULL) { ::google::protobuf::internal::ReflectionOps::Merge(from, this); } else { @@ -8709,16 +9404,16 @@ void MessageOptions::InternalSwap(MessageOptions* other) { // MessageOptions // optional bool message_set_wire_format = 1 [default = false]; - bool MessageOptions::has_message_set_wire_format() const { +bool MessageOptions::has_message_set_wire_format() const { return (_has_bits_[0] & 0x00000001u) != 0; } - void MessageOptions::set_has_message_set_wire_format() { +void MessageOptions::set_has_message_set_wire_format() { _has_bits_[0] |= 0x00000001u; } - void MessageOptions::clear_has_message_set_wire_format() { +void MessageOptions::clear_has_message_set_wire_format() { _has_bits_[0] &= ~0x00000001u; } - void MessageOptions::clear_message_set_wire_format() { +void MessageOptions::clear_message_set_wire_format() { message_set_wire_format_ = false; clear_has_message_set_wire_format(); } @@ -8733,16 +9428,16 @@ void MessageOptions::InternalSwap(MessageOptions* other) { } // optional bool no_standard_descriptor_accessor = 2 [default = false]; - bool MessageOptions::has_no_standard_descriptor_accessor() const { +bool MessageOptions::has_no_standard_descriptor_accessor() const { return (_has_bits_[0] & 0x00000002u) != 0; } - void MessageOptions::set_has_no_standard_descriptor_accessor() { +void MessageOptions::set_has_no_standard_descriptor_accessor() { _has_bits_[0] |= 0x00000002u; } - void MessageOptions::clear_has_no_standard_descriptor_accessor() { +void MessageOptions::clear_has_no_standard_descriptor_accessor() { _has_bits_[0] &= ~0x00000002u; } - void MessageOptions::clear_no_standard_descriptor_accessor() { +void MessageOptions::clear_no_standard_descriptor_accessor() { no_standard_descriptor_accessor_ = false; clear_has_no_standard_descriptor_accessor(); } @@ -8757,16 +9452,16 @@ void MessageOptions::InternalSwap(MessageOptions* other) { } // optional bool deprecated = 3 [default = false]; - bool MessageOptions::has_deprecated() const { +bool MessageOptions::has_deprecated() const { return (_has_bits_[0] & 0x00000004u) != 0; } - void MessageOptions::set_has_deprecated() { +void MessageOptions::set_has_deprecated() { _has_bits_[0] |= 0x00000004u; } - void MessageOptions::clear_has_deprecated() { +void MessageOptions::clear_has_deprecated() { _has_bits_[0] &= ~0x00000004u; } - void MessageOptions::clear_deprecated() { +void MessageOptions::clear_deprecated() { deprecated_ = false; clear_has_deprecated(); } @@ -8781,16 +9476,16 @@ void MessageOptions::InternalSwap(MessageOptions* other) { } // optional bool map_entry = 7; - bool MessageOptions::has_map_entry() const { +bool MessageOptions::has_map_entry() const { return (_has_bits_[0] & 0x00000008u) != 0; } - void MessageOptions::set_has_map_entry() { +void MessageOptions::set_has_map_entry() { _has_bits_[0] |= 0x00000008u; } - void MessageOptions::clear_has_map_entry() { +void MessageOptions::clear_has_map_entry() { _has_bits_[0] &= ~0x00000008u; } - void MessageOptions::clear_map_entry() { +void MessageOptions::clear_map_entry() { map_entry_ = false; clear_has_map_entry(); } @@ -8805,10 +9500,10 @@ void MessageOptions::InternalSwap(MessageOptions* other) { } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - int MessageOptions::uninterpreted_option_size() const { +int MessageOptions::uninterpreted_option_size() const { return uninterpreted_option_.size(); } - void MessageOptions::clear_uninterpreted_option() { +void MessageOptions::clear_uninterpreted_option() { uninterpreted_option_.Clear(); } const ::google::protobuf::UninterpretedOption& MessageOptions::uninterpreted_option(int index) const { @@ -8861,9 +9556,33 @@ const FieldOptions_CType FieldOptions::CType_MIN; const FieldOptions_CType FieldOptions::CType_MAX; const int FieldOptions::CType_ARRAYSIZE; #endif // _MSC_VER +const ::google::protobuf::EnumDescriptor* FieldOptions_JSType_descriptor() { + protobuf_AssignDescriptorsOnce(); + return FieldOptions_JSType_descriptor_; +} +bool FieldOptions_JSType_IsValid(int value) { + switch(value) { + case 0: + case 1: + case 2: + return true; + default: + return false; + } +} + +#ifndef _MSC_VER +const FieldOptions_JSType FieldOptions::JS_NORMAL; +const FieldOptions_JSType FieldOptions::JS_STRING; +const FieldOptions_JSType FieldOptions::JS_NUMBER; +const FieldOptions_JSType FieldOptions::JSType_MIN; +const FieldOptions_JSType FieldOptions::JSType_MAX; +const int FieldOptions::JSType_ARRAYSIZE; +#endif // _MSC_VER #ifndef _MSC_VER const int FieldOptions::kCtypeFieldNumber; const int FieldOptions::kPackedFieldNumber; +const int FieldOptions::kJstypeFieldNumber; const int FieldOptions::kLazyFieldNumber; const int FieldOptions::kDeprecatedFieldNumber; const int FieldOptions::kWeakFieldNumber; @@ -8871,7 +9590,7 @@ const int FieldOptions::kUninterpretedOptionFieldNumber; #endif // !_MSC_VER FieldOptions::FieldOptions() - : ::google::protobuf::Message() , _internal_metadata_(NULL) { + : ::google::protobuf::Message(), _internal_metadata_(NULL) { SharedCtor(); // @@protoc_insertion_point(constructor:google.protobuf.FieldOptions) } @@ -8891,6 +9610,7 @@ void FieldOptions::SharedCtor() { _cached_size_ = 0; ctype_ = 0; packed_ = false; + jstype_ = 0; lazy_ = false; deprecated_ = false; weak_ = false; @@ -8942,8 +9662,9 @@ void FieldOptions::Clear() { ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\ } while (0) - if (_has_bits_[0 / 32] & 31) { - ZR_(ctype_, weak_); + if (_has_bits_[0 / 32] & 63u) { + ZR_(ctype_, jstype_); + ZR_(packed_, weak_); } #undef ZR_HELPER_ @@ -9026,6 +9747,26 @@ bool FieldOptions::MergePartialFromCodedStream( } else { goto handle_unusual; } + if (input->ExpectTag(48)) goto parse_jstype; + break; + } + + // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL]; + case 6: { + if (tag == 48) { + parse_jstype: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + if (::google::protobuf::FieldOptions_JSType_IsValid(value)) { + set_jstype(static_cast< ::google::protobuf::FieldOptions_JSType >(value)); + } else { + mutable_unknown_fields()->AddVarint(6, value); + } + } else { + goto handle_unusual; + } if (input->ExpectTag(80)) goto parse_weak; break; } @@ -9049,12 +9790,15 @@ bool FieldOptions::MergePartialFromCodedStream( case 999: { if (tag == 7994) { parse_uninterpreted_option: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + DO_(input->IncrementRecursionDepth()); + parse_loop_uninterpreted_option: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( input, add_uninterpreted_option())); } else { goto handle_unusual; } - if (input->ExpectTag(7994)) goto parse_uninterpreted_option; + if (input->ExpectTag(7994)) goto parse_loop_uninterpreted_option; + input->UnsafeDecrementRecursionDepth(); if (input->ExpectAtEnd()) goto success; break; } @@ -9110,6 +9854,12 @@ void FieldOptions::SerializeWithCachedSizes( ::google::protobuf::internal::WireFormatLite::WriteBool(5, this->lazy(), output); } + // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL]; + if (has_jstype()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 6, this->jstype(), output); + } + // optional bool weak = 10 [default = false]; if (has_weak()) { ::google::protobuf::internal::WireFormatLite::WriteBool(10, this->weak(), output); @@ -9156,6 +9906,12 @@ void FieldOptions::SerializeWithCachedSizes( target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(5, this->lazy(), target); } + // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL]; + if (has_jstype()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 6, this->jstype(), target); + } + // optional bool weak = 10 [default = false]; if (has_weak()) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(10, this->weak(), target); @@ -9183,7 +9939,7 @@ void FieldOptions::SerializeWithCachedSizes( int FieldOptions::ByteSize() const { int total_size = 0; - if (_has_bits_[0 / 32] & 31) { + if (_has_bits_[0 / 32] & 63) { // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; if (has_ctype()) { total_size += 1 + @@ -9195,6 +9951,12 @@ int FieldOptions::ByteSize() const { total_size += 1 + 1; } + // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL]; + if (has_jstype()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->jstype()); + } + // optional bool lazy = 5 [default = false]; if (has_lazy()) { total_size += 1 + 1; @@ -9234,9 +9996,9 @@ int FieldOptions::ByteSize() const { void FieldOptions::MergeFrom(const ::google::protobuf::Message& from) { if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - const FieldOptions* source = - ::google::protobuf::internal::dynamic_cast_if_available<const FieldOptions*>( - &from); + const FieldOptions* source = + ::google::protobuf::internal::DynamicCastToGenerated<const FieldOptions>( + &from); if (source == NULL) { ::google::protobuf::internal::ReflectionOps::Merge(from, this); } else { @@ -9254,6 +10016,9 @@ void FieldOptions::MergeFrom(const FieldOptions& from) { if (from.has_packed()) { set_packed(from.packed()); } + if (from.has_jstype()) { + set_jstype(from.jstype()); + } if (from.has_lazy()) { set_lazy(from.lazy()); } @@ -9296,6 +10061,7 @@ void FieldOptions::Swap(FieldOptions* other) { void FieldOptions::InternalSwap(FieldOptions* other) { std::swap(ctype_, other->ctype_); std::swap(packed_, other->packed_); + std::swap(jstype_, other->jstype_); std::swap(lazy_, other->lazy_); std::swap(deprecated_, other->deprecated_); std::swap(weak_, other->weak_); @@ -9318,16 +10084,16 @@ void FieldOptions::InternalSwap(FieldOptions* other) { // FieldOptions // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; - bool FieldOptions::has_ctype() const { +bool FieldOptions::has_ctype() const { return (_has_bits_[0] & 0x00000001u) != 0; } - void FieldOptions::set_has_ctype() { +void FieldOptions::set_has_ctype() { _has_bits_[0] |= 0x00000001u; } - void FieldOptions::clear_has_ctype() { +void FieldOptions::clear_has_ctype() { _has_bits_[0] &= ~0x00000001u; } - void FieldOptions::clear_ctype() { +void FieldOptions::clear_ctype() { ctype_ = 0; clear_has_ctype(); } @@ -9343,16 +10109,16 @@ void FieldOptions::InternalSwap(FieldOptions* other) { } // optional bool packed = 2; - bool FieldOptions::has_packed() const { +bool FieldOptions::has_packed() const { return (_has_bits_[0] & 0x00000002u) != 0; } - void FieldOptions::set_has_packed() { +void FieldOptions::set_has_packed() { _has_bits_[0] |= 0x00000002u; } - void FieldOptions::clear_has_packed() { +void FieldOptions::clear_has_packed() { _has_bits_[0] &= ~0x00000002u; } - void FieldOptions::clear_packed() { +void FieldOptions::clear_packed() { packed_ = false; clear_has_packed(); } @@ -9366,17 +10132,42 @@ void FieldOptions::InternalSwap(FieldOptions* other) { // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.packed) } -// optional bool lazy = 5 [default = false]; - bool FieldOptions::has_lazy() const { +// optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL]; +bool FieldOptions::has_jstype() const { return (_has_bits_[0] & 0x00000004u) != 0; } - void FieldOptions::set_has_lazy() { +void FieldOptions::set_has_jstype() { _has_bits_[0] |= 0x00000004u; } - void FieldOptions::clear_has_lazy() { +void FieldOptions::clear_has_jstype() { _has_bits_[0] &= ~0x00000004u; } - void FieldOptions::clear_lazy() { +void FieldOptions::clear_jstype() { + jstype_ = 0; + clear_has_jstype(); +} + ::google::protobuf::FieldOptions_JSType FieldOptions::jstype() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.jstype) + return static_cast< ::google::protobuf::FieldOptions_JSType >(jstype_); +} + void FieldOptions::set_jstype(::google::protobuf::FieldOptions_JSType value) { + assert(::google::protobuf::FieldOptions_JSType_IsValid(value)); + set_has_jstype(); + jstype_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.jstype) +} + +// optional bool lazy = 5 [default = false]; +bool FieldOptions::has_lazy() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +void FieldOptions::set_has_lazy() { + _has_bits_[0] |= 0x00000008u; +} +void FieldOptions::clear_has_lazy() { + _has_bits_[0] &= ~0x00000008u; +} +void FieldOptions::clear_lazy() { lazy_ = false; clear_has_lazy(); } @@ -9391,16 +10182,16 @@ void FieldOptions::InternalSwap(FieldOptions* other) { } // optional bool deprecated = 3 [default = false]; - bool FieldOptions::has_deprecated() const { - return (_has_bits_[0] & 0x00000008u) != 0; +bool FieldOptions::has_deprecated() const { + return (_has_bits_[0] & 0x00000010u) != 0; } - void FieldOptions::set_has_deprecated() { - _has_bits_[0] |= 0x00000008u; +void FieldOptions::set_has_deprecated() { + _has_bits_[0] |= 0x00000010u; } - void FieldOptions::clear_has_deprecated() { - _has_bits_[0] &= ~0x00000008u; +void FieldOptions::clear_has_deprecated() { + _has_bits_[0] &= ~0x00000010u; } - void FieldOptions::clear_deprecated() { +void FieldOptions::clear_deprecated() { deprecated_ = false; clear_has_deprecated(); } @@ -9415,16 +10206,16 @@ void FieldOptions::InternalSwap(FieldOptions* other) { } // optional bool weak = 10 [default = false]; - bool FieldOptions::has_weak() const { - return (_has_bits_[0] & 0x00000010u) != 0; +bool FieldOptions::has_weak() const { + return (_has_bits_[0] & 0x00000020u) != 0; } - void FieldOptions::set_has_weak() { - _has_bits_[0] |= 0x00000010u; +void FieldOptions::set_has_weak() { + _has_bits_[0] |= 0x00000020u; } - void FieldOptions::clear_has_weak() { - _has_bits_[0] &= ~0x00000010u; +void FieldOptions::clear_has_weak() { + _has_bits_[0] &= ~0x00000020u; } - void FieldOptions::clear_weak() { +void FieldOptions::clear_weak() { weak_ = false; clear_has_weak(); } @@ -9439,10 +10230,10 @@ void FieldOptions::InternalSwap(FieldOptions* other) { } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - int FieldOptions::uninterpreted_option_size() const { +int FieldOptions::uninterpreted_option_size() const { return uninterpreted_option_.size(); } - void FieldOptions::clear_uninterpreted_option() { +void FieldOptions::clear_uninterpreted_option() { uninterpreted_option_.Clear(); } const ::google::protobuf::UninterpretedOption& FieldOptions::uninterpreted_option(int index) const { @@ -9479,7 +10270,7 @@ const int EnumOptions::kUninterpretedOptionFieldNumber; #endif // !_MSC_VER EnumOptions::EnumOptions() - : ::google::protobuf::Message() , _internal_metadata_(NULL) { + : ::google::protobuf::Message(), _internal_metadata_(NULL) { SharedCtor(); // @@protoc_insertion_point(constructor:google.protobuf.EnumOptions) } @@ -9602,12 +10393,15 @@ bool EnumOptions::MergePartialFromCodedStream( case 999: { if (tag == 7994) { parse_uninterpreted_option: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + DO_(input->IncrementRecursionDepth()); + parse_loop_uninterpreted_option: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( input, add_uninterpreted_option())); } else { goto handle_unusual; } - if (input->ExpectTag(7994)) goto parse_uninterpreted_option; + if (input->ExpectTag(7994)) goto parse_loop_uninterpreted_option; + input->UnsafeDecrementRecursionDepth(); if (input->ExpectAtEnd()) goto success; break; } @@ -9739,9 +10533,9 @@ int EnumOptions::ByteSize() const { void EnumOptions::MergeFrom(const ::google::protobuf::Message& from) { if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - const EnumOptions* source = - ::google::protobuf::internal::dynamic_cast_if_available<const EnumOptions*>( - &from); + const EnumOptions* source = + ::google::protobuf::internal::DynamicCastToGenerated<const EnumOptions>( + &from); if (source == NULL) { ::google::protobuf::internal::ReflectionOps::Merge(from, this); } else { @@ -9811,16 +10605,16 @@ void EnumOptions::InternalSwap(EnumOptions* other) { // EnumOptions // optional bool allow_alias = 2; - bool EnumOptions::has_allow_alias() const { +bool EnumOptions::has_allow_alias() const { return (_has_bits_[0] & 0x00000001u) != 0; } - void EnumOptions::set_has_allow_alias() { +void EnumOptions::set_has_allow_alias() { _has_bits_[0] |= 0x00000001u; } - void EnumOptions::clear_has_allow_alias() { +void EnumOptions::clear_has_allow_alias() { _has_bits_[0] &= ~0x00000001u; } - void EnumOptions::clear_allow_alias() { +void EnumOptions::clear_allow_alias() { allow_alias_ = false; clear_has_allow_alias(); } @@ -9835,16 +10629,16 @@ void EnumOptions::InternalSwap(EnumOptions* other) { } // optional bool deprecated = 3 [default = false]; - bool EnumOptions::has_deprecated() const { +bool EnumOptions::has_deprecated() const { return (_has_bits_[0] & 0x00000002u) != 0; } - void EnumOptions::set_has_deprecated() { +void EnumOptions::set_has_deprecated() { _has_bits_[0] |= 0x00000002u; } - void EnumOptions::clear_has_deprecated() { +void EnumOptions::clear_has_deprecated() { _has_bits_[0] &= ~0x00000002u; } - void EnumOptions::clear_deprecated() { +void EnumOptions::clear_deprecated() { deprecated_ = false; clear_has_deprecated(); } @@ -9859,10 +10653,10 @@ void EnumOptions::InternalSwap(EnumOptions* other) { } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - int EnumOptions::uninterpreted_option_size() const { +int EnumOptions::uninterpreted_option_size() const { return uninterpreted_option_.size(); } - void EnumOptions::clear_uninterpreted_option() { +void EnumOptions::clear_uninterpreted_option() { uninterpreted_option_.Clear(); } const ::google::protobuf::UninterpretedOption& EnumOptions::uninterpreted_option(int index) const { @@ -9898,7 +10692,7 @@ const int EnumValueOptions::kUninterpretedOptionFieldNumber; #endif // !_MSC_VER EnumValueOptions::EnumValueOptions() - : ::google::protobuf::Message() , _internal_metadata_(NULL) { + : ::google::protobuf::Message(), _internal_metadata_(NULL) { SharedCtor(); // @@protoc_insertion_point(constructor:google.protobuf.EnumValueOptions) } @@ -9993,12 +10787,15 @@ bool EnumValueOptions::MergePartialFromCodedStream( case 999: { if (tag == 7994) { parse_uninterpreted_option: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + DO_(input->IncrementRecursionDepth()); + parse_loop_uninterpreted_option: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( input, add_uninterpreted_option())); } else { goto handle_unusual; } - if (input->ExpectTag(7994)) goto parse_uninterpreted_option; + if (input->ExpectTag(7994)) goto parse_loop_uninterpreted_option; + input->UnsafeDecrementRecursionDepth(); if (input->ExpectAtEnd()) goto success; break; } @@ -10113,9 +10910,9 @@ int EnumValueOptions::ByteSize() const { void EnumValueOptions::MergeFrom(const ::google::protobuf::Message& from) { if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - const EnumValueOptions* source = - ::google::protobuf::internal::dynamic_cast_if_available<const EnumValueOptions*>( - &from); + const EnumValueOptions* source = + ::google::protobuf::internal::DynamicCastToGenerated<const EnumValueOptions>( + &from); if (source == NULL) { ::google::protobuf::internal::ReflectionOps::Merge(from, this); } else { @@ -10181,16 +10978,16 @@ void EnumValueOptions::InternalSwap(EnumValueOptions* other) { // EnumValueOptions // optional bool deprecated = 1 [default = false]; - bool EnumValueOptions::has_deprecated() const { +bool EnumValueOptions::has_deprecated() const { return (_has_bits_[0] & 0x00000001u) != 0; } - void EnumValueOptions::set_has_deprecated() { +void EnumValueOptions::set_has_deprecated() { _has_bits_[0] |= 0x00000001u; } - void EnumValueOptions::clear_has_deprecated() { +void EnumValueOptions::clear_has_deprecated() { _has_bits_[0] &= ~0x00000001u; } - void EnumValueOptions::clear_deprecated() { +void EnumValueOptions::clear_deprecated() { deprecated_ = false; clear_has_deprecated(); } @@ -10205,10 +11002,10 @@ void EnumValueOptions::InternalSwap(EnumValueOptions* other) { } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - int EnumValueOptions::uninterpreted_option_size() const { +int EnumValueOptions::uninterpreted_option_size() const { return uninterpreted_option_.size(); } - void EnumValueOptions::clear_uninterpreted_option() { +void EnumValueOptions::clear_uninterpreted_option() { uninterpreted_option_.Clear(); } const ::google::protobuf::UninterpretedOption& EnumValueOptions::uninterpreted_option(int index) const { @@ -10244,7 +11041,7 @@ const int ServiceOptions::kUninterpretedOptionFieldNumber; #endif // !_MSC_VER ServiceOptions::ServiceOptions() - : ::google::protobuf::Message() , _internal_metadata_(NULL) { + : ::google::protobuf::Message(), _internal_metadata_(NULL) { SharedCtor(); // @@protoc_insertion_point(constructor:google.protobuf.ServiceOptions) } @@ -10339,12 +11136,15 @@ bool ServiceOptions::MergePartialFromCodedStream( case 999: { if (tag == 7994) { parse_uninterpreted_option: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + DO_(input->IncrementRecursionDepth()); + parse_loop_uninterpreted_option: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( input, add_uninterpreted_option())); } else { goto handle_unusual; } - if (input->ExpectTag(7994)) goto parse_uninterpreted_option; + if (input->ExpectTag(7994)) goto parse_loop_uninterpreted_option; + input->UnsafeDecrementRecursionDepth(); if (input->ExpectAtEnd()) goto success; break; } @@ -10459,9 +11259,9 @@ int ServiceOptions::ByteSize() const { void ServiceOptions::MergeFrom(const ::google::protobuf::Message& from) { if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - const ServiceOptions* source = - ::google::protobuf::internal::dynamic_cast_if_available<const ServiceOptions*>( - &from); + const ServiceOptions* source = + ::google::protobuf::internal::DynamicCastToGenerated<const ServiceOptions>( + &from); if (source == NULL) { ::google::protobuf::internal::ReflectionOps::Merge(from, this); } else { @@ -10527,16 +11327,16 @@ void ServiceOptions::InternalSwap(ServiceOptions* other) { // ServiceOptions // optional bool deprecated = 33 [default = false]; - bool ServiceOptions::has_deprecated() const { +bool ServiceOptions::has_deprecated() const { return (_has_bits_[0] & 0x00000001u) != 0; } - void ServiceOptions::set_has_deprecated() { +void ServiceOptions::set_has_deprecated() { _has_bits_[0] |= 0x00000001u; } - void ServiceOptions::clear_has_deprecated() { +void ServiceOptions::clear_has_deprecated() { _has_bits_[0] &= ~0x00000001u; } - void ServiceOptions::clear_deprecated() { +void ServiceOptions::clear_deprecated() { deprecated_ = false; clear_has_deprecated(); } @@ -10551,10 +11351,10 @@ void ServiceOptions::InternalSwap(ServiceOptions* other) { } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - int ServiceOptions::uninterpreted_option_size() const { +int ServiceOptions::uninterpreted_option_size() const { return uninterpreted_option_.size(); } - void ServiceOptions::clear_uninterpreted_option() { +void ServiceOptions::clear_uninterpreted_option() { uninterpreted_option_.Clear(); } const ::google::protobuf::UninterpretedOption& ServiceOptions::uninterpreted_option(int index) const { @@ -10590,7 +11390,7 @@ const int MethodOptions::kUninterpretedOptionFieldNumber; #endif // !_MSC_VER MethodOptions::MethodOptions() - : ::google::protobuf::Message() , _internal_metadata_(NULL) { + : ::google::protobuf::Message(), _internal_metadata_(NULL) { SharedCtor(); // @@protoc_insertion_point(constructor:google.protobuf.MethodOptions) } @@ -10685,12 +11485,15 @@ bool MethodOptions::MergePartialFromCodedStream( case 999: { if (tag == 7994) { parse_uninterpreted_option: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + DO_(input->IncrementRecursionDepth()); + parse_loop_uninterpreted_option: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( input, add_uninterpreted_option())); } else { goto handle_unusual; } - if (input->ExpectTag(7994)) goto parse_uninterpreted_option; + if (input->ExpectTag(7994)) goto parse_loop_uninterpreted_option; + input->UnsafeDecrementRecursionDepth(); if (input->ExpectAtEnd()) goto success; break; } @@ -10805,9 +11608,9 @@ int MethodOptions::ByteSize() const { void MethodOptions::MergeFrom(const ::google::protobuf::Message& from) { if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - const MethodOptions* source = - ::google::protobuf::internal::dynamic_cast_if_available<const MethodOptions*>( - &from); + const MethodOptions* source = + ::google::protobuf::internal::DynamicCastToGenerated<const MethodOptions>( + &from); if (source == NULL) { ::google::protobuf::internal::ReflectionOps::Merge(from, this); } else { @@ -10873,16 +11676,16 @@ void MethodOptions::InternalSwap(MethodOptions* other) { // MethodOptions // optional bool deprecated = 33 [default = false]; - bool MethodOptions::has_deprecated() const { +bool MethodOptions::has_deprecated() const { return (_has_bits_[0] & 0x00000001u) != 0; } - void MethodOptions::set_has_deprecated() { +void MethodOptions::set_has_deprecated() { _has_bits_[0] |= 0x00000001u; } - void MethodOptions::clear_has_deprecated() { +void MethodOptions::clear_has_deprecated() { _has_bits_[0] &= ~0x00000001u; } - void MethodOptions::clear_deprecated() { +void MethodOptions::clear_deprecated() { deprecated_ = false; clear_has_deprecated(); } @@ -10897,10 +11700,10 @@ void MethodOptions::InternalSwap(MethodOptions* other) { } // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; - int MethodOptions::uninterpreted_option_size() const { +int MethodOptions::uninterpreted_option_size() const { return uninterpreted_option_.size(); } - void MethodOptions::clear_uninterpreted_option() { +void MethodOptions::clear_uninterpreted_option() { uninterpreted_option_.Clear(); } const ::google::protobuf::UninterpretedOption& MethodOptions::uninterpreted_option(int index) const { @@ -10936,7 +11739,7 @@ const int UninterpretedOption_NamePart::kIsExtensionFieldNumber; #endif // !_MSC_VER UninterpretedOption_NamePart::UninterpretedOption_NamePart() - : ::google::protobuf::Message() , _internal_metadata_(NULL) { + : ::google::protobuf::Message(), _internal_metadata_(NULL) { SharedCtor(); // @@protoc_insertion_point(constructor:google.protobuf.UninterpretedOption.NamePart) } @@ -10997,7 +11800,7 @@ UninterpretedOption_NamePart* UninterpretedOption_NamePart::New(::google::protob } void UninterpretedOption_NamePart::Clear() { - if (_has_bits_[0 / 32] & 3) { + if (_has_bits_[0 / 32] & 3u) { if (has_name_part()) { name_part_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); } @@ -11169,9 +11972,9 @@ int UninterpretedOption_NamePart::ByteSize() const { void UninterpretedOption_NamePart::MergeFrom(const ::google::protobuf::Message& from) { if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - const UninterpretedOption_NamePart* source = - ::google::protobuf::internal::dynamic_cast_if_available<const UninterpretedOption_NamePart*>( - &from); + const UninterpretedOption_NamePart* source = + ::google::protobuf::internal::DynamicCastToGenerated<const UninterpretedOption_NamePart>( + &from); if (source == NULL) { ::google::protobuf::internal::ReflectionOps::Merge(from, this); } else { @@ -11247,7 +12050,7 @@ const int UninterpretedOption::kAggregateValueFieldNumber; #endif // !_MSC_VER UninterpretedOption::UninterpretedOption() - : ::google::protobuf::Message() , _internal_metadata_(NULL) { + : ::google::protobuf::Message(), _internal_metadata_(NULL) { SharedCtor(); // @@protoc_insertion_point(constructor:google.protobuf.UninterpretedOption) } @@ -11322,7 +12125,7 @@ void UninterpretedOption::Clear() { ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\ } while (0) - if (_has_bits_[0 / 32] & 126) { + if (_has_bits_[0 / 32] & 126u) { ZR_(positive_int_value_, double_value_); if (has_identifier_value()) { identifier_value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); @@ -11358,13 +12161,15 @@ bool UninterpretedOption::MergePartialFromCodedStream( // repeated .google.protobuf.UninterpretedOption.NamePart name = 2; case 2: { if (tag == 18) { - parse_name: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + DO_(input->IncrementRecursionDepth()); + parse_loop_name: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( input, add_name())); } else { goto handle_unusual; } - if (input->ExpectTag(18)) goto parse_name; + if (input->ExpectTag(18)) goto parse_loop_name; + input->UnsafeDecrementRecursionDepth(); if (input->ExpectTag(26)) goto parse_identifier_value; break; } @@ -11668,9 +12473,9 @@ int UninterpretedOption::ByteSize() const { void UninterpretedOption::MergeFrom(const ::google::protobuf::Message& from) { if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - const UninterpretedOption* source = - ::google::protobuf::internal::dynamic_cast_if_available<const UninterpretedOption*>( - &from); + const UninterpretedOption* source = + ::google::protobuf::internal::DynamicCastToGenerated<const UninterpretedOption>( + &from); if (source == NULL) { ::google::protobuf::internal::ReflectionOps::Merge(from, this); } else { @@ -11756,16 +12561,16 @@ void UninterpretedOption::InternalSwap(UninterpretedOption* other) { // UninterpretedOption_NamePart // required string name_part = 1; - bool UninterpretedOption_NamePart::has_name_part() const { +bool UninterpretedOption_NamePart::has_name_part() const { return (_has_bits_[0] & 0x00000001u) != 0; } - void UninterpretedOption_NamePart::set_has_name_part() { +void UninterpretedOption_NamePart::set_has_name_part() { _has_bits_[0] |= 0x00000001u; } - void UninterpretedOption_NamePart::clear_has_name_part() { +void UninterpretedOption_NamePart::clear_has_name_part() { _has_bits_[0] &= ~0x00000001u; } - void UninterpretedOption_NamePart::clear_name_part() { +void UninterpretedOption_NamePart::clear_name_part() { name_part_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); clear_has_name_part(); } @@ -11809,16 +12614,16 @@ void UninterpretedOption::InternalSwap(UninterpretedOption* other) { } // required bool is_extension = 2; - bool UninterpretedOption_NamePart::has_is_extension() const { +bool UninterpretedOption_NamePart::has_is_extension() const { return (_has_bits_[0] & 0x00000002u) != 0; } - void UninterpretedOption_NamePart::set_has_is_extension() { +void UninterpretedOption_NamePart::set_has_is_extension() { _has_bits_[0] |= 0x00000002u; } - void UninterpretedOption_NamePart::clear_has_is_extension() { +void UninterpretedOption_NamePart::clear_has_is_extension() { _has_bits_[0] &= ~0x00000002u; } - void UninterpretedOption_NamePart::clear_is_extension() { +void UninterpretedOption_NamePart::clear_is_extension() { is_extension_ = false; clear_has_is_extension(); } @@ -11837,10 +12642,10 @@ void UninterpretedOption::InternalSwap(UninterpretedOption* other) { // UninterpretedOption // repeated .google.protobuf.UninterpretedOption.NamePart name = 2; - int UninterpretedOption::name_size() const { +int UninterpretedOption::name_size() const { return name_.size(); } - void UninterpretedOption::clear_name() { +void UninterpretedOption::clear_name() { name_.Clear(); } const ::google::protobuf::UninterpretedOption_NamePart& UninterpretedOption::name(int index) const { @@ -11867,16 +12672,16 @@ UninterpretedOption::mutable_name() { } // optional string identifier_value = 3; - bool UninterpretedOption::has_identifier_value() const { +bool UninterpretedOption::has_identifier_value() const { return (_has_bits_[0] & 0x00000002u) != 0; } - void UninterpretedOption::set_has_identifier_value() { +void UninterpretedOption::set_has_identifier_value() { _has_bits_[0] |= 0x00000002u; } - void UninterpretedOption::clear_has_identifier_value() { +void UninterpretedOption::clear_has_identifier_value() { _has_bits_[0] &= ~0x00000002u; } - void UninterpretedOption::clear_identifier_value() { +void UninterpretedOption::clear_identifier_value() { identifier_value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); clear_has_identifier_value(); } @@ -11920,16 +12725,16 @@ UninterpretedOption::mutable_name() { } // optional uint64 positive_int_value = 4; - bool UninterpretedOption::has_positive_int_value() const { +bool UninterpretedOption::has_positive_int_value() const { return (_has_bits_[0] & 0x00000004u) != 0; } - void UninterpretedOption::set_has_positive_int_value() { +void UninterpretedOption::set_has_positive_int_value() { _has_bits_[0] |= 0x00000004u; } - void UninterpretedOption::clear_has_positive_int_value() { +void UninterpretedOption::clear_has_positive_int_value() { _has_bits_[0] &= ~0x00000004u; } - void UninterpretedOption::clear_positive_int_value() { +void UninterpretedOption::clear_positive_int_value() { positive_int_value_ = GOOGLE_ULONGLONG(0); clear_has_positive_int_value(); } @@ -11944,16 +12749,16 @@ UninterpretedOption::mutable_name() { } // optional int64 negative_int_value = 5; - bool UninterpretedOption::has_negative_int_value() const { +bool UninterpretedOption::has_negative_int_value() const { return (_has_bits_[0] & 0x00000008u) != 0; } - void UninterpretedOption::set_has_negative_int_value() { +void UninterpretedOption::set_has_negative_int_value() { _has_bits_[0] |= 0x00000008u; } - void UninterpretedOption::clear_has_negative_int_value() { +void UninterpretedOption::clear_has_negative_int_value() { _has_bits_[0] &= ~0x00000008u; } - void UninterpretedOption::clear_negative_int_value() { +void UninterpretedOption::clear_negative_int_value() { negative_int_value_ = GOOGLE_LONGLONG(0); clear_has_negative_int_value(); } @@ -11968,16 +12773,16 @@ UninterpretedOption::mutable_name() { } // optional double double_value = 6; - bool UninterpretedOption::has_double_value() const { +bool UninterpretedOption::has_double_value() const { return (_has_bits_[0] & 0x00000010u) != 0; } - void UninterpretedOption::set_has_double_value() { +void UninterpretedOption::set_has_double_value() { _has_bits_[0] |= 0x00000010u; } - void UninterpretedOption::clear_has_double_value() { +void UninterpretedOption::clear_has_double_value() { _has_bits_[0] &= ~0x00000010u; } - void UninterpretedOption::clear_double_value() { +void UninterpretedOption::clear_double_value() { double_value_ = 0; clear_has_double_value(); } @@ -11992,16 +12797,16 @@ UninterpretedOption::mutable_name() { } // optional bytes string_value = 7; - bool UninterpretedOption::has_string_value() const { +bool UninterpretedOption::has_string_value() const { return (_has_bits_[0] & 0x00000020u) != 0; } - void UninterpretedOption::set_has_string_value() { +void UninterpretedOption::set_has_string_value() { _has_bits_[0] |= 0x00000020u; } - void UninterpretedOption::clear_has_string_value() { +void UninterpretedOption::clear_has_string_value() { _has_bits_[0] &= ~0x00000020u; } - void UninterpretedOption::clear_string_value() { +void UninterpretedOption::clear_string_value() { string_value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); clear_has_string_value(); } @@ -12045,16 +12850,16 @@ UninterpretedOption::mutable_name() { } // optional string aggregate_value = 8; - bool UninterpretedOption::has_aggregate_value() const { +bool UninterpretedOption::has_aggregate_value() const { return (_has_bits_[0] & 0x00000040u) != 0; } - void UninterpretedOption::set_has_aggregate_value() { +void UninterpretedOption::set_has_aggregate_value() { _has_bits_[0] |= 0x00000040u; } - void UninterpretedOption::clear_has_aggregate_value() { +void UninterpretedOption::clear_has_aggregate_value() { _has_bits_[0] &= ~0x00000040u; } - void UninterpretedOption::clear_aggregate_value() { +void UninterpretedOption::clear_aggregate_value() { aggregate_value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); clear_has_aggregate_value(); } @@ -12110,7 +12915,7 @@ const int SourceCodeInfo_Location::kLeadingDetachedCommentsFieldNumber; #endif // !_MSC_VER SourceCodeInfo_Location::SourceCodeInfo_Location() - : ::google::protobuf::Message() , _internal_metadata_(NULL) { + : ::google::protobuf::Message(), _internal_metadata_(NULL) { SharedCtor(); // @@protoc_insertion_point(constructor:google.protobuf.SourceCodeInfo.Location) } @@ -12172,7 +12977,7 @@ SourceCodeInfo_Location* SourceCodeInfo_Location::New(::google::protobuf::Arena* } void SourceCodeInfo_Location::Clear() { - if (_has_bits_[0 / 32] & 12) { + if (_has_bits_[0 / 32] & 12u) { if (has_leading_comments()) { leading_comments_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); } @@ -12513,9 +13318,9 @@ int SourceCodeInfo_Location::ByteSize() const { void SourceCodeInfo_Location::MergeFrom(const ::google::protobuf::Message& from) { if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - const SourceCodeInfo_Location* source = - ::google::protobuf::internal::dynamic_cast_if_available<const SourceCodeInfo_Location*>( - &from); + const SourceCodeInfo_Location* source = + ::google::protobuf::internal::DynamicCastToGenerated<const SourceCodeInfo_Location>( + &from); if (source == NULL) { ::google::protobuf::internal::ReflectionOps::Merge(from, this); } else { @@ -12591,7 +13396,7 @@ const int SourceCodeInfo::kLocationFieldNumber; #endif // !_MSC_VER SourceCodeInfo::SourceCodeInfo() - : ::google::protobuf::Message() , _internal_metadata_(NULL) { + : ::google::protobuf::Message(), _internal_metadata_(NULL) { SharedCtor(); // @@protoc_insertion_point(constructor:google.protobuf.SourceCodeInfo) } @@ -12668,13 +13473,15 @@ bool SourceCodeInfo::MergePartialFromCodedStream( // repeated .google.protobuf.SourceCodeInfo.Location location = 1; case 1: { if (tag == 10) { - parse_location: - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + DO_(input->IncrementRecursionDepth()); + parse_loop_location: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( input, add_location())); } else { goto handle_unusual; } - if (input->ExpectTag(10)) goto parse_location; + if (input->ExpectTag(10)) goto parse_loop_location; + input->UnsafeDecrementRecursionDepth(); if (input->ExpectAtEnd()) goto success; break; } @@ -12759,9 +13566,9 @@ int SourceCodeInfo::ByteSize() const { void SourceCodeInfo::MergeFrom(const ::google::protobuf::Message& from) { if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); - const SourceCodeInfo* source = - ::google::protobuf::internal::dynamic_cast_if_available<const SourceCodeInfo*>( - &from); + const SourceCodeInfo* source = + ::google::protobuf::internal::DynamicCastToGenerated<const SourceCodeInfo>( + &from); if (source == NULL) { ::google::protobuf::internal::ReflectionOps::Merge(from, this); } else { @@ -12817,10 +13624,10 @@ void SourceCodeInfo::InternalSwap(SourceCodeInfo* other) { // SourceCodeInfo_Location // repeated int32 path = 1 [packed = true]; - int SourceCodeInfo_Location::path_size() const { +int SourceCodeInfo_Location::path_size() const { return path_.size(); } - void SourceCodeInfo_Location::clear_path() { +void SourceCodeInfo_Location::clear_path() { path_.Clear(); } ::google::protobuf::int32 SourceCodeInfo_Location::path(int index) const { @@ -12847,10 +13654,10 @@ SourceCodeInfo_Location::mutable_path() { } // repeated int32 span = 2 [packed = true]; - int SourceCodeInfo_Location::span_size() const { +int SourceCodeInfo_Location::span_size() const { return span_.size(); } - void SourceCodeInfo_Location::clear_span() { +void SourceCodeInfo_Location::clear_span() { span_.Clear(); } ::google::protobuf::int32 SourceCodeInfo_Location::span(int index) const { @@ -12877,16 +13684,16 @@ SourceCodeInfo_Location::mutable_span() { } // optional string leading_comments = 3; - bool SourceCodeInfo_Location::has_leading_comments() const { +bool SourceCodeInfo_Location::has_leading_comments() const { return (_has_bits_[0] & 0x00000004u) != 0; } - void SourceCodeInfo_Location::set_has_leading_comments() { +void SourceCodeInfo_Location::set_has_leading_comments() { _has_bits_[0] |= 0x00000004u; } - void SourceCodeInfo_Location::clear_has_leading_comments() { +void SourceCodeInfo_Location::clear_has_leading_comments() { _has_bits_[0] &= ~0x00000004u; } - void SourceCodeInfo_Location::clear_leading_comments() { +void SourceCodeInfo_Location::clear_leading_comments() { leading_comments_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); clear_has_leading_comments(); } @@ -12930,16 +13737,16 @@ SourceCodeInfo_Location::mutable_span() { } // optional string trailing_comments = 4; - bool SourceCodeInfo_Location::has_trailing_comments() const { +bool SourceCodeInfo_Location::has_trailing_comments() const { return (_has_bits_[0] & 0x00000008u) != 0; } - void SourceCodeInfo_Location::set_has_trailing_comments() { +void SourceCodeInfo_Location::set_has_trailing_comments() { _has_bits_[0] |= 0x00000008u; } - void SourceCodeInfo_Location::clear_has_trailing_comments() { +void SourceCodeInfo_Location::clear_has_trailing_comments() { _has_bits_[0] &= ~0x00000008u; } - void SourceCodeInfo_Location::clear_trailing_comments() { +void SourceCodeInfo_Location::clear_trailing_comments() { trailing_comments_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); clear_has_trailing_comments(); } @@ -12983,10 +13790,10 @@ SourceCodeInfo_Location::mutable_span() { } // repeated string leading_detached_comments = 6; - int SourceCodeInfo_Location::leading_detached_comments_size() const { +int SourceCodeInfo_Location::leading_detached_comments_size() const { return leading_detached_comments_.size(); } - void SourceCodeInfo_Location::clear_leading_detached_comments() { +void SourceCodeInfo_Location::clear_leading_detached_comments() { leading_detached_comments_.Clear(); } const ::std::string& SourceCodeInfo_Location::leading_detached_comments(int index) const { @@ -13041,10 +13848,10 @@ SourceCodeInfo_Location::mutable_leading_detached_comments() { // SourceCodeInfo // repeated .google.protobuf.SourceCodeInfo.Location location = 1; - int SourceCodeInfo::location_size() const { +int SourceCodeInfo::location_size() const { return location_.size(); } - void SourceCodeInfo::clear_location() { +void SourceCodeInfo::clear_location() { location_.Clear(); } const ::google::protobuf::SourceCodeInfo_Location& SourceCodeInfo::location(int index) const { diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h index d8cba659..b887b8cb 100644 --- a/src/google/protobuf/descriptor.pb.h +++ b/src/google/protobuf/descriptor.pb.h @@ -42,6 +42,7 @@ class FileDescriptorSet; class FileDescriptorProto; class DescriptorProto; class DescriptorProto_ExtensionRange; +class DescriptorProto_ReservedRange; class FieldDescriptorProto; class OneofDescriptorProto; class EnumDescriptorProto; @@ -155,6 +156,26 @@ inline bool FieldOptions_CType_Parse( return ::google::protobuf::internal::ParseNamedEnum<FieldOptions_CType>( FieldOptions_CType_descriptor(), name, value); } +enum FieldOptions_JSType { + FieldOptions_JSType_JS_NORMAL = 0, + FieldOptions_JSType_JS_STRING = 1, + FieldOptions_JSType_JS_NUMBER = 2 +}; +LIBPROTOBUF_EXPORT bool FieldOptions_JSType_IsValid(int value); +const FieldOptions_JSType FieldOptions_JSType_JSType_MIN = FieldOptions_JSType_JS_NORMAL; +const FieldOptions_JSType FieldOptions_JSType_JSType_MAX = FieldOptions_JSType_JS_NUMBER; +const int FieldOptions_JSType_JSType_ARRAYSIZE = FieldOptions_JSType_JSType_MAX + 1; + +LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* FieldOptions_JSType_descriptor(); +inline const ::std::string& FieldOptions_JSType_Name(FieldOptions_JSType value) { + return ::google::protobuf::internal::NameOfEnum( + FieldOptions_JSType_descriptor(), value); +} +inline bool FieldOptions_JSType_Parse( + const ::std::string& name, FieldOptions_JSType* value) { + return ::google::protobuf::internal::ParseNamedEnum<FieldOptions_JSType>( + FieldOptions_JSType_descriptor(), name, value); +} // =================================================================== class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message { @@ -591,6 +612,105 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::proto }; // ------------------------------------------------------------------- +class LIBPROTOBUF_EXPORT DescriptorProto_ReservedRange : public ::google::protobuf::Message { + public: + DescriptorProto_ReservedRange(); + virtual ~DescriptorProto_ReservedRange(); + + DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange& from); + + inline DescriptorProto_ReservedRange& operator=(const DescriptorProto_ReservedRange& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const DescriptorProto_ReservedRange& default_instance(); + + void Swap(DescriptorProto_ReservedRange* other); + + // implements Message ---------------------------------------------- + + inline DescriptorProto_ReservedRange* New() const { return New(NULL); } + + DescriptorProto_ReservedRange* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const DescriptorProto_ReservedRange& from); + void MergeFrom(const DescriptorProto_ReservedRange& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(DescriptorProto_ReservedRange* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional int32 start = 1; + bool has_start() const; + void clear_start(); + static const int kStartFieldNumber = 1; + ::google::protobuf::int32 start() const; + void set_start(::google::protobuf::int32 value); + + // optional int32 end = 2; + bool has_end() const; + void clear_end(); + static const int kEndFieldNumber = 2; + ::google::protobuf::int32 end() const; + void set_end(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto.ReservedRange) + private: + inline void set_has_start(); + inline void clear_has_start(); + inline void set_has_end(); + inline void clear_has_end(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + ::google::protobuf::int32 start_; + ::google::protobuf::int32 end_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); + + void InitAsDefaultInstance(); + static DescriptorProto_ReservedRange* default_instance_; +}; +// ------------------------------------------------------------------- + class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message { public: DescriptorProto(); @@ -654,6 +774,7 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message { // nested types ---------------------------------------------------- typedef DescriptorProto_ExtensionRange ExtensionRange; + typedef DescriptorProto_ReservedRange ReservedRange; // accessors ------------------------------------------------------- @@ -750,6 +871,34 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message { ::google::protobuf::MessageOptions* release_options(); void set_allocated_options(::google::protobuf::MessageOptions* options); + // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9; + int reserved_range_size() const; + void clear_reserved_range(); + static const int kReservedRangeFieldNumber = 9; + const ::google::protobuf::DescriptorProto_ReservedRange& reserved_range(int index) const; + ::google::protobuf::DescriptorProto_ReservedRange* mutable_reserved_range(int index); + ::google::protobuf::DescriptorProto_ReservedRange* add_reserved_range(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ReservedRange >& + reserved_range() const; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ReservedRange >* + mutable_reserved_range(); + + // repeated string reserved_name = 10; + int reserved_name_size() const; + void clear_reserved_name(); + static const int kReservedNameFieldNumber = 10; + 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, 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(const char* value); + void add_reserved_name(const char* value, size_t size); + const ::google::protobuf::RepeatedPtrField< ::std::string>& reserved_name() const; + ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_reserved_name(); + // @@protoc_insertion_point(class_scope:google.protobuf.DescriptorProto) private: inline void set_has_name(); @@ -768,6 +917,8 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message { ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange > extension_range_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto > oneof_decl_; ::google::protobuf::MessageOptions* options_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ReservedRange > reserved_range_; + ::google::protobuf::RepeatedPtrField< ::std::string> reserved_name_; friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); @@ -1837,6 +1988,18 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message { ::std::string* release_objc_class_prefix(); void set_allocated_objc_class_prefix(::std::string* objc_class_prefix); + // optional string csharp_namespace = 37; + bool has_csharp_namespace() const; + void clear_csharp_namespace(); + static const int kCsharpNamespaceFieldNumber = 37; + const ::std::string& csharp_namespace() const; + void set_csharp_namespace(const ::std::string& value); + void set_csharp_namespace(const char* value); + void set_csharp_namespace(const char* value, size_t size); + ::std::string* mutable_csharp_namespace(); + ::std::string* release_csharp_namespace(); + void set_allocated_csharp_namespace(::std::string* csharp_namespace); + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; int uninterpreted_option_size() const; void clear_uninterpreted_option(); @@ -1878,6 +2041,8 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message { inline void clear_has_cc_enable_arenas(); inline void set_has_objc_class_prefix(); inline void clear_has_objc_class_prefix(); + inline void set_has_csharp_namespace(); + inline void clear_has_csharp_namespace(); ::google::protobuf::internal::ExtensionSet _extensions_; @@ -1893,6 +2058,7 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message { int optimize_for_; ::google::protobuf::internal::ArenaStringPtr go_package_; ::google::protobuf::internal::ArenaStringPtr objc_class_prefix_; + ::google::protobuf::internal::ArenaStringPtr csharp_namespace_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; bool java_generic_services_; bool py_generic_services_; @@ -2129,6 +2295,31 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message { return FieldOptions_CType_Parse(name, value); } + typedef FieldOptions_JSType JSType; + static const JSType JS_NORMAL = FieldOptions_JSType_JS_NORMAL; + static const JSType JS_STRING = FieldOptions_JSType_JS_STRING; + static const JSType JS_NUMBER = FieldOptions_JSType_JS_NUMBER; + static inline bool JSType_IsValid(int value) { + return FieldOptions_JSType_IsValid(value); + } + static const JSType JSType_MIN = + FieldOptions_JSType_JSType_MIN; + static const JSType JSType_MAX = + FieldOptions_JSType_JSType_MAX; + static const int JSType_ARRAYSIZE = + FieldOptions_JSType_JSType_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + JSType_descriptor() { + return FieldOptions_JSType_descriptor(); + } + static inline const ::std::string& JSType_Name(JSType value) { + return FieldOptions_JSType_Name(value); + } + static inline bool JSType_Parse(const ::std::string& name, + JSType* value) { + return FieldOptions_JSType_Parse(name, value); + } + // accessors ------------------------------------------------------- // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; @@ -2145,6 +2336,13 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message { bool packed() const; void set_packed(bool value); + // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL]; + bool has_jstype() const; + void clear_jstype(); + static const int kJstypeFieldNumber = 6; + ::google::protobuf::FieldOptions_JSType jstype() const; + void set_jstype(::google::protobuf::FieldOptions_JSType value); + // optional bool lazy = 5 [default = false]; bool has_lazy() const; void clear_lazy(); @@ -2185,6 +2383,8 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message { inline void clear_has_ctype(); inline void set_has_packed(); inline void clear_has_packed(); + inline void set_has_jstype(); + inline void clear_has_jstype(); inline void set_has_lazy(); inline void clear_has_lazy(); inline void set_has_deprecated(); @@ -2198,11 +2398,12 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message { ::google::protobuf::uint32 _has_bits_[1]; mutable int _cached_size_; int ctype_; + int jstype_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; bool packed_; bool lazy_; bool deprecated_; bool weak_; - ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto(); friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto(); @@ -3739,6 +3940,58 @@ inline void DescriptorProto_ExtensionRange::set_end(::google::protobuf::int32 va // ------------------------------------------------------------------- +// DescriptorProto_ReservedRange + +// optional int32 start = 1; +inline bool DescriptorProto_ReservedRange::has_start() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void DescriptorProto_ReservedRange::set_has_start() { + _has_bits_[0] |= 0x00000001u; +} +inline void DescriptorProto_ReservedRange::clear_has_start() { + _has_bits_[0] &= ~0x00000001u; +} +inline void DescriptorProto_ReservedRange::clear_start() { + start_ = 0; + clear_has_start(); +} +inline ::google::protobuf::int32 DescriptorProto_ReservedRange::start() const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ReservedRange.start) + return start_; +} +inline void DescriptorProto_ReservedRange::set_start(::google::protobuf::int32 value) { + set_has_start(); + start_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ReservedRange.start) +} + +// optional int32 end = 2; +inline bool DescriptorProto_ReservedRange::has_end() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void DescriptorProto_ReservedRange::set_has_end() { + _has_bits_[0] |= 0x00000002u; +} +inline void DescriptorProto_ReservedRange::clear_has_end() { + _has_bits_[0] &= ~0x00000002u; +} +inline void DescriptorProto_ReservedRange::clear_end() { + end_ = 0; + clear_has_end(); +} +inline ::google::protobuf::int32 DescriptorProto_ReservedRange::end() const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.ReservedRange.end) + return end_; +} +inline void DescriptorProto_ReservedRange::set_end(::google::protobuf::int32 value) { + set_has_end(); + end_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.ReservedRange.end) +} + +// ------------------------------------------------------------------- + // DescriptorProto // optional string name = 1; @@ -4017,6 +4270,90 @@ inline void DescriptorProto::set_allocated_options(::google::protobuf::MessageOp // @@protoc_insertion_point(field_set_allocated:google.protobuf.DescriptorProto.options) } +// repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9; +inline int DescriptorProto::reserved_range_size() const { + return reserved_range_.size(); +} +inline void DescriptorProto::clear_reserved_range() { + reserved_range_.Clear(); +} +inline const ::google::protobuf::DescriptorProto_ReservedRange& DescriptorProto::reserved_range(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.reserved_range) + return reserved_range_.Get(index); +} +inline ::google::protobuf::DescriptorProto_ReservedRange* DescriptorProto::mutable_reserved_range(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.reserved_range) + return reserved_range_.Mutable(index); +} +inline ::google::protobuf::DescriptorProto_ReservedRange* DescriptorProto::add_reserved_range() { + // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.reserved_range) + return reserved_range_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ReservedRange >& +DescriptorProto::reserved_range() const { + // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.reserved_range) + return reserved_range_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ReservedRange >* +DescriptorProto::mutable_reserved_range() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.reserved_range) + return &reserved_range_; +} + +// repeated string reserved_name = 10; +inline int DescriptorProto::reserved_name_size() const { + return reserved_name_.size(); +} +inline void DescriptorProto::clear_reserved_name() { + reserved_name_.Clear(); +} +inline const ::std::string& DescriptorProto::reserved_name(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.reserved_name) + return reserved_name_.Get(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) { + // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.reserved_name) + reserved_name_.Mutable(index)->assign(value); +} +inline void DescriptorProto::set_reserved_name(int index, const char* value) { + 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::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(const char* value) { + 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 ::google::protobuf::RepeatedPtrField< ::std::string>& +DescriptorProto::reserved_name() const { + // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.reserved_name) + return reserved_name_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +DescriptorProto::mutable_reserved_name() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.reserved_name) + return &reserved_name_; +} + // ------------------------------------------------------------------- // FieldDescriptorProto @@ -5502,6 +5839,59 @@ inline void FileOptions::set_allocated_objc_class_prefix(::std::string* objc_cla // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.objc_class_prefix) } +// optional string csharp_namespace = 37; +inline bool FileOptions::has_csharp_namespace() const { + return (_has_bits_[0] & 0x00002000u) != 0; +} +inline void FileOptions::set_has_csharp_namespace() { + _has_bits_[0] |= 0x00002000u; +} +inline void FileOptions::clear_has_csharp_namespace() { + _has_bits_[0] &= ~0x00002000u; +} +inline void FileOptions::clear_csharp_namespace() { + csharp_namespace_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_csharp_namespace(); +} +inline const ::std::string& FileOptions::csharp_namespace() const { + // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.csharp_namespace) + return csharp_namespace_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void FileOptions::set_csharp_namespace(const ::std::string& value) { + set_has_csharp_namespace(); + csharp_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.csharp_namespace) +} +inline void FileOptions::set_csharp_namespace(const char* value) { + set_has_csharp_namespace(); + csharp_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.csharp_namespace) +} +inline void FileOptions::set_csharp_namespace(const char* value, size_t size) { + set_has_csharp_namespace(); + csharp_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.csharp_namespace) +} +inline ::std::string* FileOptions::mutable_csharp_namespace() { + set_has_csharp_namespace(); + // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.csharp_namespace) + return csharp_namespace_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* FileOptions::release_csharp_namespace() { + clear_has_csharp_namespace(); + return csharp_namespace_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void FileOptions::set_allocated_csharp_namespace(::std::string* csharp_namespace) { + if (csharp_namespace != NULL) { + set_has_csharp_namespace(); + } else { + clear_has_csharp_namespace(); + } + csharp_namespace_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), csharp_namespace); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.csharp_namespace) +} + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; inline int FileOptions::uninterpreted_option_size() const { return uninterpreted_option_.size(); @@ -5715,15 +6105,40 @@ inline void FieldOptions::set_packed(bool value) { // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.packed) } +// optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL]; +inline bool FieldOptions::has_jstype() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FieldOptions::set_has_jstype() { + _has_bits_[0] |= 0x00000004u; +} +inline void FieldOptions::clear_has_jstype() { + _has_bits_[0] &= ~0x00000004u; +} +inline void FieldOptions::clear_jstype() { + jstype_ = 0; + clear_has_jstype(); +} +inline ::google::protobuf::FieldOptions_JSType FieldOptions::jstype() const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.jstype) + return static_cast< ::google::protobuf::FieldOptions_JSType >(jstype_); +} +inline void FieldOptions::set_jstype(::google::protobuf::FieldOptions_JSType value) { + assert(::google::protobuf::FieldOptions_JSType_IsValid(value)); + set_has_jstype(); + jstype_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.FieldOptions.jstype) +} + // optional bool lazy = 5 [default = false]; inline bool FieldOptions::has_lazy() const { - return (_has_bits_[0] & 0x00000004u) != 0; + return (_has_bits_[0] & 0x00000008u) != 0; } inline void FieldOptions::set_has_lazy() { - _has_bits_[0] |= 0x00000004u; + _has_bits_[0] |= 0x00000008u; } inline void FieldOptions::clear_has_lazy() { - _has_bits_[0] &= ~0x00000004u; + _has_bits_[0] &= ~0x00000008u; } inline void FieldOptions::clear_lazy() { lazy_ = false; @@ -5741,13 +6156,13 @@ inline void FieldOptions::set_lazy(bool value) { // optional bool deprecated = 3 [default = false]; inline bool FieldOptions::has_deprecated() const { - return (_has_bits_[0] & 0x00000008u) != 0; + return (_has_bits_[0] & 0x00000010u) != 0; } inline void FieldOptions::set_has_deprecated() { - _has_bits_[0] |= 0x00000008u; + _has_bits_[0] |= 0x00000010u; } inline void FieldOptions::clear_has_deprecated() { - _has_bits_[0] &= ~0x00000008u; + _has_bits_[0] &= ~0x00000010u; } inline void FieldOptions::clear_deprecated() { deprecated_ = false; @@ -5765,13 +6180,13 @@ inline void FieldOptions::set_deprecated(bool value) { // optional bool weak = 10 [default = false]; inline bool FieldOptions::has_weak() const { - return (_has_bits_[0] & 0x00000010u) != 0; + return (_has_bits_[0] & 0x00000020u) != 0; } inline void FieldOptions::set_has_weak() { - _has_bits_[0] |= 0x00000010u; + _has_bits_[0] |= 0x00000020u; } inline void FieldOptions::clear_has_weak() { - _has_bits_[0] &= ~0x00000010u; + _has_bits_[0] &= ~0x00000020u; } inline void FieldOptions::clear_weak() { weak_ = false; @@ -6678,6 +7093,48 @@ SourceCodeInfo::mutable_location() { } #endif // !PROTOBUF_INLINE_NOT_IN_HEADERS +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + // @@protoc_insertion_point(namespace_scope) @@ -6708,6 +7165,11 @@ template <> inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FieldOptions_CType>() { return ::google::protobuf::FieldOptions_CType_descriptor(); } +template <> struct is_proto_enum< ::google::protobuf::FieldOptions_JSType> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::FieldOptions_JSType>() { + return ::google::protobuf::FieldOptions_JSType_descriptor(); +} } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/descriptor.proto b/src/google/protobuf/descriptor.proto index 367b16e5..20a60080 100644 --- a/src/google/protobuf/descriptor.proto +++ b/src/google/protobuf/descriptor.proto @@ -42,6 +42,8 @@ syntax = "proto2"; package google.protobuf; option java_package = "com.google.protobuf"; option java_outer_classname = "DescriptorProtos"; +option csharp_namespace = "Google.ProtocolBuffers.DescriptorProtos"; +option objc_class_prefix = "GPB"; // descriptor.proto must be optimized for speed because reflection-based // algorithms don't work during bootstrapping. @@ -104,6 +106,18 @@ message DescriptorProto { 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; } // Describes a field within a message. @@ -249,11 +263,11 @@ message MethodDescriptorProto { // * 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. -// Object-C plugin) and your porject 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: +// 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. @@ -351,6 +365,9 @@ message FileOptions { // 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; + // The parser stores options it doesn't recognize here. See above. repeated UninterpretedOption uninterpreted_option = 999; @@ -437,10 +454,31 @@ message FieldOptions { // 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. + // 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). By default these types are + // represented as JavaScript strings. This avoids loss of precision that can + // happen when a large value is converted to a floating point JavaScript + // numbers. Specifying JS_NUMBER for the jstype causes the generated + // JavaScript code to use the JavaScript "number" type instead of strings. + // 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 @@ -481,8 +519,6 @@ message FieldOptions { // 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; diff --git a/src/google/protobuf/descriptor_database.h b/src/google/protobuf/descriptor_database.h index 934e4022..86002d56 100644 --- a/src/google/protobuf/descriptor_database.h +++ b/src/google/protobuf/descriptor_database.h @@ -312,7 +312,7 @@ class LIBPROTOBUF_EXPORT EncodedDescriptorDatabase : public DescriptorDatabase { // A DescriptorDatabase that fetches files from a given pool. class LIBPROTOBUF_EXPORT DescriptorPoolDatabase : public DescriptorDatabase { public: - DescriptorPoolDatabase(const DescriptorPool& pool); + explicit DescriptorPoolDatabase(const DescriptorPool& pool); ~DescriptorPoolDatabase(); // implements DescriptorDatabase ----------------------------------- @@ -341,7 +341,7 @@ class LIBPROTOBUF_EXPORT MergedDescriptorDatabase : public DescriptorDatabase { // 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. - MergedDescriptorDatabase(const vector<DescriptorDatabase*>& sources); + explicit MergedDescriptorDatabase(const vector<DescriptorDatabase*>& sources); ~MergedDescriptorDatabase(); // implements DescriptorDatabase ----------------------------------- diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc index fdce3d78..760df097 100644 --- a/src/google/protobuf/descriptor_unittest.cc +++ b/src/google/protobuf/descriptor_unittest.cc @@ -139,6 +139,14 @@ DescriptorProto::ExtensionRange* AddExtensionRange(DescriptorProto* parent, 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; +} + EnumValueDescriptorProto* AddEnumValue(EnumDescriptorProto* enum_proto, const string& name, int number) { EnumValueDescriptorProto* result = enum_proto->add_value(); @@ -1720,6 +1728,84 @@ TEST_F(ExtensionDescriptorTest, DuplicateFieldNumber) { // =================================================================== +// Test reserved fields. +class ReservedDescriptorTest : public testing::Test { + protected: + virtual void SetUp() { + // 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_ != NULL); + + 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")); +}; + +// =================================================================== + class MiscTest : public testing::Test { protected: // Function which makes a field descriptor of the given type. @@ -2997,10 +3083,10 @@ class ValidationErrorTest : public testing::Test { protected: // Parse file_text as a FileDescriptorProto in text format and add it // to the DescriptorPool. Expect no errors. - void BuildFile(const string& file_text) { + const FileDescriptor* BuildFile(const string& file_text) { FileDescriptorProto file_proto; - ASSERT_TRUE(TextFormat::ParseFromString(file_text, &file_proto)); - ASSERT_TRUE(pool_.BuildFile(file_proto) != NULL); + 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 @@ -3251,6 +3337,102 @@ TEST_F(ValidationErrorTest, OverlappingExtensionRanges) { "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, InvalidDefaults) { BuildFileWithErrors( "name: \"foo.proto\" " @@ -3399,6 +3581,48 @@ TEST_F(ValidationErrorTest, FieldOneofIndexNegative) { "range for type \"Foo\".\n"); } +TEST_F(ValidationErrorTest, OneofFieldsConsecutiveDefinition) { + // Fields belonging to the same oneof must be defined consecutively. + BuildFileWithWarnings( + "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: OTHER: 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. + BuildFileWithWarnings( + "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: OTHER: 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: OTHER: Fields in the same oneof must be defined " + "consecutively. \"foo2\" cannot be defined before the completion of the " + "\"bars\" oneof definition.\n"); +} + TEST_F(ValidationErrorTest, FieldNumberConflict) { BuildFileWithErrors( "name: \"foo.proto\" " @@ -5293,6 +5517,22 @@ TEST_F(ValidationErrorTest, ValidateProto3LiteRuntime) { "in proto3.\n"); } +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. diff --git a/src/google/protobuf/duration.pb.cc b/src/google/protobuf/duration.pb.cc new file mode 100644 index 00000000..f78fce21 --- /dev/null +++ b/src/google/protobuf/duration.pb.cc @@ -0,0 +1,407 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/duration.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "google/protobuf/duration.pb.h" + +#include <algorithm> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/once.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/wire_format_lite_inl.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/reflection_ops.h> +#include <google/protobuf/wire_format.h> +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { + +namespace { + +const ::google::protobuf::Descriptor* Duration_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Duration_reflection_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_google_2fprotobuf_2fduration_2eproto() { + protobuf_AddDesc_google_2fprotobuf_2fduration_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "google/protobuf/duration.proto"); + GOOGLE_CHECK(file != NULL); + Duration_descriptor_ = file->message_type(0); + static const int Duration_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Duration, seconds_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Duration, nanos_), + }; + Duration_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + Duration_descriptor_, + Duration::default_instance_, + Duration_offsets_, + -1, + -1, + -1, + sizeof(Duration), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Duration, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Duration, _is_default_instance_)); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_google_2fprotobuf_2fduration_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Duration_descriptor_, &Duration::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_google_2fprotobuf_2fduration_2eproto() { + delete Duration::default_instance_; + delete Duration_reflection_; +} + +void protobuf_AddDesc_google_2fprotobuf_2fduration_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\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(\005BH\n\023com.google.protobufB\rDu" + "rationProtoP\001\240\001\001\242\002\003GPB\252\002\026Google.Protocol" + "Buffersb\006proto3", 175); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "google/protobuf/duration.proto", &protobuf_RegisterTypes); + Duration::default_instance_ = new Duration(); + Duration::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_google_2fprotobuf_2fduration_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_google_2fprotobuf_2fduration_2eproto { + StaticDescriptorInitializer_google_2fprotobuf_2fduration_2eproto() { + protobuf_AddDesc_google_2fprotobuf_2fduration_2eproto(); + } +} static_descriptor_initializer_google_2fprotobuf_2fduration_2eproto_; + +namespace { + +static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD; +static void MergeFromFail(int line) { + GOOGLE_CHECK(false) << __FILE__ << ":" << line; +} + +} // namespace + + +// =================================================================== + +#ifndef _MSC_VER +const int Duration::kSecondsFieldNumber; +const int Duration::kNanosFieldNumber; +#endif // !_MSC_VER + +Duration::Duration() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:google.protobuf.Duration) +} + +void Duration::InitAsDefaultInstance() { + _is_default_instance_ = true; +} + +Duration::Duration(const Duration& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:google.protobuf.Duration) +} + +void Duration::SharedCtor() { + _is_default_instance_ = false; + _cached_size_ = 0; + seconds_ = GOOGLE_LONGLONG(0); + nanos_ = 0; +} + +Duration::~Duration() { + // @@protoc_insertion_point(destructor:google.protobuf.Duration) + SharedDtor(); +} + +void Duration::SharedDtor() { + if (this != default_instance_) { + } +} + +void Duration::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Duration::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Duration_descriptor_; +} + +const Duration& Duration::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fduration_2eproto(); + return *default_instance_; +} + +Duration* Duration::default_instance_ = NULL; + +Duration* Duration::New(::google::protobuf::Arena* arena) const { + Duration* n = new Duration; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void Duration::Clear() { +#define ZR_HELPER_(f) reinterpret_cast<char*>(\ + &reinterpret_cast<Duration*>(16)->f) + +#define ZR_(first, last) do {\ + ::memset(&first, 0,\ + ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\ +} while (0) + + ZR_(seconds_, nanos_); + +#undef ZR_HELPER_ +#undef ZR_ + +} + +bool Duration::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:google.protobuf.Duration) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional int64 seconds = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( + input, &seconds_))); + + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_nanos; + break; + } + + // optional int32 nanos = 2; + case 2: { + if (tag == 16) { + parse_nanos: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &nanos_))); + + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:google.protobuf.Duration) + return true; +failure: + // @@protoc_insertion_point(parse_failure:google.protobuf.Duration) + return false; +#undef DO_ +} + +void Duration::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:google.protobuf.Duration) + // optional int64 seconds = 1; + if (this->seconds() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteInt64(1, this->seconds(), output); + } + + // optional int32 nanos = 2; + if (this->nanos() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->nanos(), output); + } + + // @@protoc_insertion_point(serialize_end:google.protobuf.Duration) +} + +::google::protobuf::uint8* Duration::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Duration) + // optional int64 seconds = 1; + if (this->seconds() != 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(1, this->seconds(), target); + } + + // optional int32 nanos = 2; + if (this->nanos() != 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->nanos(), target); + } + + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Duration) + return target; +} + +int Duration::ByteSize() const { + int total_size = 0; + + // optional int64 seconds = 1; + if (this->seconds() != 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int64Size( + this->seconds()); + } + + // optional int32 nanos = 2; + if (this->nanos() != 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->nanos()); + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Duration::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const Duration* source = + ::google::protobuf::internal::DynamicCastToGenerated<const Duration>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Duration::MergeFrom(const Duration& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from.seconds() != 0) { + set_seconds(from.seconds()); + } + if (from.nanos() != 0) { + set_nanos(from.nanos()); + } +} + +void Duration::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Duration::CopyFrom(const Duration& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Duration::IsInitialized() const { + + return true; +} + +void Duration::Swap(Duration* other) { + if (other == this) return; + InternalSwap(other); +} +void Duration::InternalSwap(Duration* other) { + std::swap(seconds_, other->seconds_); + std::swap(nanos_, other->nanos_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata Duration::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Duration_descriptor_; + metadata.reflection = Duration_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// Duration + +// optional int64 seconds = 1; +void Duration::clear_seconds() { + seconds_ = GOOGLE_LONGLONG(0); +} + ::google::protobuf::int64 Duration::seconds() const { + // @@protoc_insertion_point(field_get:google.protobuf.Duration.seconds) + return seconds_; +} + void Duration::set_seconds(::google::protobuf::int64 value) { + + seconds_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Duration.seconds) +} + +// optional int32 nanos = 2; +void Duration::clear_nanos() { + nanos_ = 0; +} + ::google::protobuf::int32 Duration::nanos() const { + // @@protoc_insertion_point(field_get:google.protobuf.Duration.nanos) + return nanos_; +} + void Duration::set_nanos(::google::protobuf::int32 value) { + + nanos_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Duration.nanos) +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// @@protoc_insertion_point(namespace_scope) + +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) diff --git a/src/google/protobuf/duration.pb.h b/src/google/protobuf/duration.pb.h new file mode 100644 index 00000000..215a52c4 --- /dev/null +++ b/src/google/protobuf/duration.pb.h @@ -0,0 +1,172 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/duration.proto + +#ifndef PROTOBUF_google_2fprotobuf_2fduration_2eproto__INCLUDED +#define PROTOBUF_google_2fprotobuf_2fduration_2eproto__INCLUDED + +#include <string> + +#include <google/protobuf/stubs/common.h> + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#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 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include <google/protobuf/arena.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/metadata.h> +#include <google/protobuf/message.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/unknown_field_set.h> +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { + +// Internal implementation detail -- do not call these. +void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fduration_2eproto(); +void protobuf_AssignDesc_google_2fprotobuf_2fduration_2eproto(); +void protobuf_ShutdownFile_google_2fprotobuf_2fduration_2eproto(); + +class Duration; + +// =================================================================== + +class LIBPROTOBUF_EXPORT Duration : public ::google::protobuf::Message { + public: + Duration(); + virtual ~Duration(); + + Duration(const Duration& from); + + inline Duration& operator=(const Duration& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Duration& default_instance(); + + void Swap(Duration* other); + + // implements Message ---------------------------------------------- + + inline Duration* New() const { return New(NULL); } + + Duration* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Duration& from); + void MergeFrom(const Duration& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Duration* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional int64 seconds = 1; + void clear_seconds(); + static const int kSecondsFieldNumber = 1; + ::google::protobuf::int64 seconds() const; + void set_seconds(::google::protobuf::int64 value); + + // optional int32 nanos = 2; + void clear_nanos(); + static const int kNanosFieldNumber = 2; + ::google::protobuf::int32 nanos() const; + void set_nanos(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:google.protobuf.Duration) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::int64 seconds_; + ::google::protobuf::int32 nanos_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fduration_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fduration_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fduration_2eproto(); + + void InitAsDefaultInstance(); + static Duration* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// Duration + +// optional int64 seconds = 1; +inline void Duration::clear_seconds() { + seconds_ = GOOGLE_LONGLONG(0); +} +inline ::google::protobuf::int64 Duration::seconds() const { + // @@protoc_insertion_point(field_get:google.protobuf.Duration.seconds) + return seconds_; +} +inline void Duration::set_seconds(::google::protobuf::int64 value) { + + seconds_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Duration.seconds) +} + +// optional int32 nanos = 2; +inline void Duration::clear_nanos() { + nanos_ = 0; +} +inline ::google::protobuf::int32 Duration::nanos() const { + // @@protoc_insertion_point(field_get:google.protobuf.Duration.nanos) + return nanos_; +} +inline void Duration::set_nanos(::google::protobuf::int32 value) { + + nanos_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Duration.nanos) +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS + +// @@protoc_insertion_point(namespace_scope) + +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_google_2fprotobuf_2fduration_2eproto__INCLUDED diff --git a/src/google/protobuf/duration.proto b/src/google/protobuf/duration.proto index c6dd4adc..e466341a 100644 --- a/src/google/protobuf/duration.proto +++ b/src/google/protobuf/duration.proto @@ -35,7 +35,8 @@ option java_generate_equals_and_hash = true; option java_multiple_files = true; option java_outer_classname = "DurationProto"; option java_package = "com.google.protobuf"; - +option csharp_namespace = "Google.ProtocolBuffers"; +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 diff --git a/src/google/protobuf/empty.pb.cc b/src/google/protobuf/empty.pb.cc new file mode 100644 index 00000000..1a9a6661 --- /dev/null +++ b/src/google/protobuf/empty.pb.cc @@ -0,0 +1,282 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/empty.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "google/protobuf/empty.pb.h" + +#include <algorithm> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/once.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/wire_format_lite_inl.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/reflection_ops.h> +#include <google/protobuf/wire_format.h> +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { + +namespace { + +const ::google::protobuf::Descriptor* Empty_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Empty_reflection_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_google_2fprotobuf_2fempty_2eproto() { + protobuf_AddDesc_google_2fprotobuf_2fempty_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "google/protobuf/empty.proto"); + GOOGLE_CHECK(file != NULL); + Empty_descriptor_ = file->message_type(0); + static const int Empty_offsets_[1] = { + }; + Empty_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + Empty_descriptor_, + Empty::default_instance_, + Empty_offsets_, + -1, + -1, + -1, + sizeof(Empty), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Empty, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Empty, _is_default_instance_)); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_google_2fprotobuf_2fempty_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Empty_descriptor_, &Empty::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_google_2fprotobuf_2fempty_2eproto() { + delete Empty::default_instance_; + delete Empty_reflection_; +} + +void protobuf_AddDesc_google_2fprotobuf_2fempty_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\033google/protobuf/empty.proto\022\017google.pr" + "otobuf\"\007\n\005EmptyB)\n\023com.google.protobufB\n" + "EmptyProtoP\001\242\002\003GPBb\006proto3", 106); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "google/protobuf/empty.proto", &protobuf_RegisterTypes); + Empty::default_instance_ = new Empty(); + Empty::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_google_2fprotobuf_2fempty_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_google_2fprotobuf_2fempty_2eproto { + StaticDescriptorInitializer_google_2fprotobuf_2fempty_2eproto() { + protobuf_AddDesc_google_2fprotobuf_2fempty_2eproto(); + } +} static_descriptor_initializer_google_2fprotobuf_2fempty_2eproto_; + +namespace { + +static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD; +static void MergeFromFail(int line) { + GOOGLE_CHECK(false) << __FILE__ << ":" << line; +} + +} // namespace + + +// =================================================================== + +#ifndef _MSC_VER +#endif // !_MSC_VER + +Empty::Empty() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:google.protobuf.Empty) +} + +void Empty::InitAsDefaultInstance() { + _is_default_instance_ = true; +} + +Empty::Empty(const Empty& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:google.protobuf.Empty) +} + +void Empty::SharedCtor() { + _is_default_instance_ = false; + _cached_size_ = 0; +} + +Empty::~Empty() { + // @@protoc_insertion_point(destructor:google.protobuf.Empty) + SharedDtor(); +} + +void Empty::SharedDtor() { + if (this != default_instance_) { + } +} + +void Empty::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Empty::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Empty_descriptor_; +} + +const Empty& Empty::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fempty_2eproto(); + return *default_instance_; +} + +Empty* Empty::default_instance_ = NULL; + +Empty* Empty::New(::google::protobuf::Arena* arena) const { + Empty* n = new Empty; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void Empty::Clear() { +} + +bool Empty::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:google.protobuf.Empty) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + } +success: + // @@protoc_insertion_point(parse_success:google.protobuf.Empty) + return true; +failure: + // @@protoc_insertion_point(parse_failure:google.protobuf.Empty) + return false; +#undef DO_ +} + +void Empty::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:google.protobuf.Empty) + // @@protoc_insertion_point(serialize_end:google.protobuf.Empty) +} + +::google::protobuf::uint8* Empty::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Empty) + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Empty) + return target; +} + +int Empty::ByteSize() const { + int total_size = 0; + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Empty::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const Empty* source = + ::google::protobuf::internal::DynamicCastToGenerated<const Empty>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Empty::MergeFrom(const Empty& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); +} + +void Empty::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Empty::CopyFrom(const Empty& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Empty::IsInitialized() const { + + return true; +} + +void Empty::Swap(Empty* other) { + if (other == this) return; + InternalSwap(other); +} +void Empty::InternalSwap(Empty* other) { + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata Empty::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Empty_descriptor_; + metadata.reflection = Empty_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// Empty + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// @@protoc_insertion_point(namespace_scope) + +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) diff --git a/src/google/protobuf/empty.pb.h b/src/google/protobuf/empty.pb.h new file mode 100644 index 00000000..20876bea --- /dev/null +++ b/src/google/protobuf/empty.pb.h @@ -0,0 +1,130 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/empty.proto + +#ifndef PROTOBUF_google_2fprotobuf_2fempty_2eproto__INCLUDED +#define PROTOBUF_google_2fprotobuf_2fempty_2eproto__INCLUDED + +#include <string> + +#include <google/protobuf/stubs/common.h> + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#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 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include <google/protobuf/arena.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/metadata.h> +#include <google/protobuf/message.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/unknown_field_set.h> +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { + +// Internal implementation detail -- do not call these. +void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fempty_2eproto(); +void protobuf_AssignDesc_google_2fprotobuf_2fempty_2eproto(); +void protobuf_ShutdownFile_google_2fprotobuf_2fempty_2eproto(); + +class Empty; + +// =================================================================== + +class LIBPROTOBUF_EXPORT Empty : public ::google::protobuf::Message { + public: + Empty(); + virtual ~Empty(); + + Empty(const Empty& from); + + inline Empty& operator=(const Empty& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Empty& default_instance(); + + void Swap(Empty* other); + + // implements Message ---------------------------------------------- + + inline Empty* New() const { return New(NULL); } + + Empty* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Empty& from); + void MergeFrom(const Empty& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Empty* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // @@protoc_insertion_point(class_scope:google.protobuf.Empty) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fempty_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fempty_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fempty_2eproto(); + + void InitAsDefaultInstance(); + static Empty* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// Empty + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS + +// @@protoc_insertion_point(namespace_scope) + +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_google_2fprotobuf_2fempty_2eproto__INCLUDED diff --git a/src/google/protobuf/empty.proto b/src/google/protobuf/empty.proto index 46087d59..94df0397 100644 --- a/src/google/protobuf/empty.proto +++ b/src/google/protobuf/empty.proto @@ -34,6 +34,7 @@ package google.protobuf; option java_multiple_files = true; option java_outer_classname = "EmptyProto"; option java_package = "com.google.protobuf"; +option objc_class_prefix = "GPB"; // A generic empty message that you can re-use to avoid defining duplicated diff --git a/src/google/protobuf/extension_set.cc b/src/google/protobuf/extension_set.cc index 03b38dd0..649ae184 100644 --- a/src/google/protobuf/extension_set.cc +++ b/src/google/protobuf/extension_set.cc @@ -314,7 +314,7 @@ void ExtensionSet::Add##CAMELCASE(int number, FieldType type, \ extension->is_repeated = true; \ extension->is_packed = packed; \ extension->repeated_##LOWERCASE##_value = \ - Arena::Create<RepeatedField<LOWERCASE> >(arena_, arena_); \ + Arena::CreateMessage<RepeatedField<LOWERCASE> >(arena_); \ } else { \ GOOGLE_DCHECK_TYPE(*extension, REPEATED, UPPERCASE); \ GOOGLE_DCHECK_EQ(extension->is_packed, packed); \ @@ -359,43 +359,43 @@ void* ExtensionSet::MutableRawRepeatedField(int number, FieldType field_type, static_cast<WireFormatLite::FieldType>(field_type))) { case WireFormatLite::CPPTYPE_INT32: extension->repeated_int32_value = - Arena::Create<RepeatedField<int32> >(arena_, arena_); + Arena::CreateMessage<RepeatedField<int32> >(arena_); break; case WireFormatLite::CPPTYPE_INT64: extension->repeated_int64_value = - Arena::Create<RepeatedField<int64> >(arena_, arena_); + Arena::CreateMessage<RepeatedField<int64> >(arena_); break; case WireFormatLite::CPPTYPE_UINT32: extension->repeated_uint32_value = - Arena::Create<RepeatedField<uint32> >(arena_, arena_); + Arena::CreateMessage<RepeatedField<uint32> >(arena_); break; case WireFormatLite::CPPTYPE_UINT64: extension->repeated_uint64_value = - Arena::Create<RepeatedField<uint64> >(arena_, arena_); + Arena::CreateMessage<RepeatedField<uint64> >(arena_); break; case WireFormatLite::CPPTYPE_DOUBLE: extension->repeated_double_value = - Arena::Create<RepeatedField<double> >(arena_, arena_); + Arena::CreateMessage<RepeatedField<double> >(arena_); break; case WireFormatLite::CPPTYPE_FLOAT: extension->repeated_float_value = - Arena::Create<RepeatedField<float> >(arena_, arena_); + Arena::CreateMessage<RepeatedField<float> >(arena_); break; case WireFormatLite::CPPTYPE_BOOL: extension->repeated_bool_value = - Arena::Create<RepeatedField<bool> >(arena_, arena_); + Arena::CreateMessage<RepeatedField<bool> >(arena_); break; case WireFormatLite::CPPTYPE_ENUM: extension->repeated_enum_value = - Arena::Create<RepeatedField<int> >(arena_, arena_); + Arena::CreateMessage<RepeatedField<int> >(arena_); break; case WireFormatLite::CPPTYPE_STRING: extension->repeated_string_value = - Arena::Create<RepeatedPtrField< ::std::string> >(arena_, arena_); + Arena::CreateMessage<RepeatedPtrField< ::std::string> >(arena_); break; case WireFormatLite::CPPTYPE_MESSAGE: extension->repeated_message_value = - Arena::Create<RepeatedPtrField<MessageLite> >(arena_, arena_); + Arena::CreateMessage<RepeatedPtrField<MessageLite> >(arena_); break; } } @@ -468,7 +468,7 @@ void ExtensionSet::AddEnum(int number, FieldType type, extension->is_repeated = true; extension->is_packed = packed; extension->repeated_enum_value = - Arena::Create<RepeatedField<int> >(arena_, arena_); + Arena::CreateMessage<RepeatedField<int> >(arena_); } else { GOOGLE_DCHECK_TYPE(*extension, REPEATED, ENUM); GOOGLE_DCHECK_EQ(extension->is_packed, packed); @@ -529,7 +529,7 @@ string* ExtensionSet::AddString(int number, FieldType type, extension->is_repeated = true; extension->is_packed = false; extension->repeated_string_value = - Arena::Create<RepeatedPtrField<string> >(arena_, arena_); + Arena::CreateMessage<RepeatedPtrField<string> >(arena_); } else { GOOGLE_DCHECK_TYPE(*extension, REPEATED, STRING); } @@ -632,6 +632,35 @@ void ExtensionSet::SetAllocatedMessage(int number, FieldType type, extension->is_cleared = false; } +void ExtensionSet::UnsafeArenaSetAllocatedMessage( + int number, FieldType type, const FieldDescriptor* descriptor, + MessageLite* message) { + if (message == NULL) { + 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, MESSAGE); + if (extension->is_lazy) { + extension->lazymessage_value->UnsafeArenaSetAllocatedMessage(message); + } else { + if (arena_ == NULL) { + delete extension->message_value; + } + extension->message_value = message; + } + } + extension->is_cleared = false; +} + + MessageLite* ExtensionSet::ReleaseMessage(int number, const MessageLite& prototype) { map<int, Extension>::iterator iter = extensions_.find(number); @@ -712,7 +741,7 @@ MessageLite* ExtensionSet::AddMessage(int number, FieldType type, GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE); extension->is_repeated = true; extension->repeated_message_value = - Arena::Create<RepeatedPtrField<MessageLite> >(arena_, arena_); + Arena::CreateMessage<RepeatedPtrField<MessageLite> >(arena_); } else { GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE); } @@ -866,7 +895,7 @@ void ExtensionSet::InternalExtensionMergeFrom( case WireFormatLite::CPPTYPE_##UPPERCASE: \ if (is_new) { \ extension->repeated_##LOWERCASE##_value = \ - Arena::Create<REPEATED_TYPE >(arena_, arena_); \ + Arena::CreateMessage<REPEATED_TYPE >(arena_); \ } \ extension->repeated_##LOWERCASE##_value->MergeFrom( \ *other_extension.repeated_##LOWERCASE##_value); \ @@ -886,7 +915,7 @@ void ExtensionSet::InternalExtensionMergeFrom( case WireFormatLite::CPPTYPE_MESSAGE: if (is_new) { extension->repeated_message_value = - Arena::Create<RepeatedPtrField<MessageLite> >(arena_, arena_); + Arena::CreateMessage<RepeatedPtrField<MessageLite> >(arena_); } // We can't call RepeatedPtrField<MessageLite>::MergeFrom() because // it would attempt to allocate new objects. diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h index 6d6702b3..c371e011 100644 --- a/src/google/protobuf/extension_set.h +++ b/src/google/protobuf/extension_set.h @@ -194,7 +194,7 @@ class LIBPROTOBUF_EXPORT ExtensionSet { // 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. Otheriwse, + // 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 @@ -262,6 +262,9 @@ class LIBPROTOBUF_EXPORT ExtensionSet { void SetAllocatedMessage(int number, FieldType type, const FieldDescriptor* descriptor, MessageLite* message); + void UnsafeArenaSetAllocatedMessage(int number, FieldType type, + const FieldDescriptor* descriptor, + MessageLite* message); MessageLite* ReleaseMessage(int number, const MessageLite& prototype); MessageLite* UnsafeArenaReleaseMessage( int number, const MessageLite& prototype); @@ -432,6 +435,7 @@ class LIBPROTOBUF_EXPORT ExtensionSet { const MessageLite& prototype) const = 0; virtual MessageLite* MutableMessage(const MessageLite& prototype) = 0; virtual void SetAllocatedMessage(MessageLite *message) = 0; + virtual void UnsafeArenaSetAllocatedMessage(MessageLite *message) = 0; virtual MessageLite* ReleaseMessage(const MessageLite& prototype) = 0; virtual MessageLite* UnsafeArenaReleaseMessage( const MessageLite& prototype) = 0; diff --git a/src/google/protobuf/extension_set_heavy.cc b/src/google/protobuf/extension_set_heavy.cc index 796e7a5f..330bd828 100644 --- a/src/google/protobuf/extension_set_heavy.cc +++ b/src/google/protobuf/extension_set_heavy.cc @@ -221,7 +221,7 @@ MessageLite* ExtensionSet::AddMessage(const FieldDescriptor* descriptor, GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE); extension->is_repeated = true; extension->repeated_message_value = - ::google::protobuf::Arena::Create<RepeatedPtrField<MessageLite> >(arena_, arena_); + ::google::protobuf::Arena::CreateMessage<RepeatedPtrField<MessageLite> >(arena_); } else { GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE); } diff --git a/src/google/protobuf/field_mask.pb.cc b/src/google/protobuf/field_mask.pb.cc new file mode 100644 index 00000000..68314fd3 --- /dev/null +++ b/src/google/protobuf/field_mask.pb.cc @@ -0,0 +1,394 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/field_mask.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "google/protobuf/field_mask.pb.h" + +#include <algorithm> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/once.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/wire_format_lite_inl.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/reflection_ops.h> +#include <google/protobuf/wire_format.h> +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { + +namespace { + +const ::google::protobuf::Descriptor* FieldMask_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FieldMask_reflection_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_google_2fprotobuf_2ffield_5fmask_2eproto() { + protobuf_AddDesc_google_2fprotobuf_2ffield_5fmask_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "google/protobuf/field_mask.proto"); + GOOGLE_CHECK(file != NULL); + FieldMask_descriptor_ = file->message_type(0); + static const int FieldMask_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldMask, paths_), + }; + FieldMask_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + FieldMask_descriptor_, + FieldMask::default_instance_, + FieldMask_offsets_, + -1, + -1, + -1, + sizeof(FieldMask), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldMask, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldMask, _is_default_instance_)); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_google_2fprotobuf_2ffield_5fmask_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FieldMask_descriptor_, &FieldMask::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_google_2fprotobuf_2ffield_5fmask_2eproto() { + delete FieldMask::default_instance_; + delete FieldMask_reflection_; +} + +void protobuf_AddDesc_google_2fprotobuf_2ffield_5fmask_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n google/protobuf/field_mask.proto\022\017goog" + "le.protobuf\"\032\n\tFieldMask\022\r\n\005paths\030\001 \003(\tB" + "F\n\023com.google.protobufB\016FieldMaskProtoP\001" + "\242\002\003GPB\252\002\026Google.ProtocolBuffersb\006proto3", 159); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "google/protobuf/field_mask.proto", &protobuf_RegisterTypes); + FieldMask::default_instance_ = new FieldMask(); + FieldMask::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_google_2fprotobuf_2ffield_5fmask_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_google_2fprotobuf_2ffield_5fmask_2eproto { + StaticDescriptorInitializer_google_2fprotobuf_2ffield_5fmask_2eproto() { + protobuf_AddDesc_google_2fprotobuf_2ffield_5fmask_2eproto(); + } +} static_descriptor_initializer_google_2fprotobuf_2ffield_5fmask_2eproto_; + +namespace { + +static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD; +static void MergeFromFail(int line) { + GOOGLE_CHECK(false) << __FILE__ << ":" << line; +} + +} // namespace + + +// =================================================================== + +#ifndef _MSC_VER +const int FieldMask::kPathsFieldNumber; +#endif // !_MSC_VER + +FieldMask::FieldMask() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:google.protobuf.FieldMask) +} + +void FieldMask::InitAsDefaultInstance() { + _is_default_instance_ = true; +} + +FieldMask::FieldMask(const FieldMask& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:google.protobuf.FieldMask) +} + +void FieldMask::SharedCtor() { + _is_default_instance_ = false; + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; +} + +FieldMask::~FieldMask() { + // @@protoc_insertion_point(destructor:google.protobuf.FieldMask) + SharedDtor(); +} + +void FieldMask::SharedDtor() { + if (this != default_instance_) { + } +} + +void FieldMask::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FieldMask::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FieldMask_descriptor_; +} + +const FieldMask& FieldMask::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2ffield_5fmask_2eproto(); + return *default_instance_; +} + +FieldMask* FieldMask::default_instance_ = NULL; + +FieldMask* FieldMask::New(::google::protobuf::Arena* arena) const { + FieldMask* n = new FieldMask; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void FieldMask::Clear() { + paths_.Clear(); +} + +bool FieldMask::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:google.protobuf.FieldMask) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated string paths = 1; + case 1: { + if (tag == 10) { + parse_paths: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->add_paths())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->paths(this->paths_size() - 1).data(), + this->paths(this->paths_size() - 1).length(), + ::google::protobuf::internal::WireFormat::PARSE, + "google.protobuf.FieldMask.paths"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(10)) goto parse_paths; + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:google.protobuf.FieldMask) + return true; +failure: + // @@protoc_insertion_point(parse_failure:google.protobuf.FieldMask) + return false; +#undef DO_ +} + +void FieldMask::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:google.protobuf.FieldMask) + // repeated string paths = 1; + for (int i = 0; i < this->paths_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->paths(i).data(), this->paths(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.FieldMask.paths"); + ::google::protobuf::internal::WireFormatLite::WriteString( + 1, this->paths(i), output); + } + + // @@protoc_insertion_point(serialize_end:google.protobuf.FieldMask) +} + +::google::protobuf::uint8* FieldMask::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FieldMask) + // repeated string paths = 1; + for (int i = 0; i < this->paths_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->paths(i).data(), this->paths(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.FieldMask.paths"); + target = ::google::protobuf::internal::WireFormatLite:: + WriteStringToArray(1, this->paths(i), target); + } + + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FieldMask) + return target; +} + +int FieldMask::ByteSize() const { + int total_size = 0; + + // repeated string paths = 1; + total_size += 1 * this->paths_size(); + for (int i = 0; i < this->paths_size(); i++) { + total_size += ::google::protobuf::internal::WireFormatLite::StringSize( + this->paths(i)); + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FieldMask::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const FieldMask* source = + ::google::protobuf::internal::DynamicCastToGenerated<const FieldMask>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FieldMask::MergeFrom(const FieldMask& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + paths_.MergeFrom(from.paths_); +} + +void FieldMask::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FieldMask::CopyFrom(const FieldMask& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FieldMask::IsInitialized() const { + + return true; +} + +void FieldMask::Swap(FieldMask* other) { + if (other == this) return; + InternalSwap(other); +} +void FieldMask::InternalSwap(FieldMask* other) { + paths_.UnsafeArenaSwap(&other->paths_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata FieldMask::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FieldMask_descriptor_; + metadata.reflection = FieldMask_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// FieldMask + +// repeated string paths = 1; +int FieldMask::paths_size() const { + return paths_.size(); +} +void FieldMask::clear_paths() { + paths_.Clear(); +} + const ::std::string& FieldMask::paths(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldMask.paths) + return paths_.Get(index); +} + ::std::string* FieldMask::mutable_paths(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.FieldMask.paths) + return paths_.Mutable(index); +} + void FieldMask::set_paths(int index, const ::std::string& value) { + // @@protoc_insertion_point(field_set:google.protobuf.FieldMask.paths) + paths_.Mutable(index)->assign(value); +} + void FieldMask::set_paths(int index, const char* value) { + paths_.Mutable(index)->assign(value); + // @@protoc_insertion_point(field_set_char:google.protobuf.FieldMask.paths) +} + 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) +} + ::std::string* FieldMask::add_paths() { + return paths_.Add(); +} + void FieldMask::add_paths(const ::std::string& value) { + paths_.Add()->assign(value); + // @@protoc_insertion_point(field_add:google.protobuf.FieldMask.paths) +} + void FieldMask::add_paths(const char* value) { + paths_.Add()->assign(value); + // @@protoc_insertion_point(field_add_char:google.protobuf.FieldMask.paths) +} + 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) +} + const ::google::protobuf::RepeatedPtrField< ::std::string>& +FieldMask::paths() const { + // @@protoc_insertion_point(field_list:google.protobuf.FieldMask.paths) + return paths_; +} + ::google::protobuf::RepeatedPtrField< ::std::string>* +FieldMask::mutable_paths() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.FieldMask.paths) + return &paths_; +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// @@protoc_insertion_point(namespace_scope) + +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) diff --git a/src/google/protobuf/field_mask.pb.h b/src/google/protobuf/field_mask.pb.h new file mode 100644 index 00000000..7189fd79 --- /dev/null +++ b/src/google/protobuf/field_mask.pb.h @@ -0,0 +1,201 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/field_mask.proto + +#ifndef PROTOBUF_google_2fprotobuf_2ffield_5fmask_2eproto__INCLUDED +#define PROTOBUF_google_2fprotobuf_2ffield_5fmask_2eproto__INCLUDED + +#include <string> + +#include <google/protobuf/stubs/common.h> + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#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 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include <google/protobuf/arena.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/metadata.h> +#include <google/protobuf/message.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/unknown_field_set.h> +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { + +// Internal implementation detail -- do not call these. +void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ffield_5fmask_2eproto(); +void protobuf_AssignDesc_google_2fprotobuf_2ffield_5fmask_2eproto(); +void protobuf_ShutdownFile_google_2fprotobuf_2ffield_5fmask_2eproto(); + +class FieldMask; + +// =================================================================== + +class LIBPROTOBUF_EXPORT FieldMask : public ::google::protobuf::Message { + public: + FieldMask(); + virtual ~FieldMask(); + + FieldMask(const FieldMask& from); + + inline FieldMask& operator=(const FieldMask& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FieldMask& default_instance(); + + void Swap(FieldMask* other); + + // implements Message ---------------------------------------------- + + inline FieldMask* New() const { return New(NULL); } + + FieldMask* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FieldMask& from); + void MergeFrom(const FieldMask& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(FieldMask* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated string paths = 1; + int paths_size() const; + void clear_paths(); + static const int kPathsFieldNumber = 1; + 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, 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(const char* value); + void add_paths(const char* value, size_t size); + const ::google::protobuf::RepeatedPtrField< ::std::string>& paths() const; + ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_paths(); + + // @@protoc_insertion_point(class_scope:google.protobuf.FieldMask) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::RepeatedPtrField< ::std::string> paths_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ffield_5fmask_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2ffield_5fmask_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2ffield_5fmask_2eproto(); + + void InitAsDefaultInstance(); + static FieldMask* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// FieldMask + +// repeated string paths = 1; +inline int FieldMask::paths_size() const { + return paths_.size(); +} +inline void FieldMask::clear_paths() { + paths_.Clear(); +} +inline const ::std::string& FieldMask::paths(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.FieldMask.paths) + return paths_.Get(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) { + // @@protoc_insertion_point(field_set:google.protobuf.FieldMask.paths) + paths_.Mutable(index)->assign(value); +} +inline void FieldMask::set_paths(int index, const char* value) { + 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::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(const char* value) { + 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 ::google::protobuf::RepeatedPtrField< ::std::string>& +FieldMask::paths() const { + // @@protoc_insertion_point(field_list:google.protobuf.FieldMask.paths) + return paths_; +} +inline ::google::protobuf::RepeatedPtrField< ::std::string>* +FieldMask::mutable_paths() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.FieldMask.paths) + return &paths_; +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS + +// @@protoc_insertion_point(namespace_scope) + +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_google_2fprotobuf_2ffield_5fmask_2eproto__INCLUDED diff --git a/src/google/protobuf/field_mask.proto b/src/google/protobuf/field_mask.proto index 492d4b06..35b1acc3 100644 --- a/src/google/protobuf/field_mask.proto +++ b/src/google/protobuf/field_mask.proto @@ -34,6 +34,8 @@ package google.protobuf; option java_multiple_files = true; option java_outer_classname = "FieldMaskProto"; option java_package = "com.google.protobuf"; +option csharp_namespace = "Google.ProtocolBuffers"; +option objc_class_prefix = "GPB"; // `FieldMask` represents a set of symbolic field paths, for example: diff --git a/src/google/protobuf/generated_message_reflection.h b/src/google/protobuf/generated_message_reflection.h index 4dddf6c7..dc8abb98 100644 --- a/src/google/protobuf/generated_message_reflection.h +++ b/src/google/protobuf/generated_message_reflection.h @@ -40,6 +40,7 @@ #include <string> #include <vector> +#include <google/protobuf/stubs/casts.h> #include <google/protobuf/stubs/common.h> // TODO(jasonh): Remove this once the compiler change to directly include this // is released to components. @@ -597,6 +598,42 @@ inline To dynamic_cast_if_available(From from) { #endif } +// Tries to downcast this message to a generated message type. +// Returns NULL if this class is not an instance of T. +// +// This is like dynamic_cast_if_available, except it works even when +// dynamic_cast is not available by using Reflection. However it only works +// with Message objects. +// +// TODO(haberman): can we remove dynamic_cast_if_available in favor of this? +template <typename T> +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*>(NULL); + (void)unused; + +#if defined(GOOGLE_PROTOBUF_NO_RTTI) || \ + (defined(_MSC_VER) && !defined(_CPPRTTI)) + bool ok = &T::default_instance() == + from->GetReflection()->GetMessageFactory()->GetPrototype( + from->GetDescriptor()); + return ok ? down_cast<T*>(from) : NULL; +#else + return dynamic_cast<T*>(from); +#endif +} + +template <typename T> +T* DynamicCastToGenerated(Message* from) { + const Message* message_const = from; + return const_cast<T*>(DynamicCastToGenerated<const T>(message_const)); +} + } // namespace internal } // namespace protobuf diff --git a/src/google/protobuf/generated_message_util.h b/src/google/protobuf/generated_message_util.h index 678f92a7..6357e27d 100644 --- a/src/google/protobuf/generated_message_util.h +++ b/src/google/protobuf/generated_message_util.h @@ -47,6 +47,10 @@ namespace google { namespace protobuf { + +class Arena; +namespace io { class CodedInputStream; } + namespace internal { @@ -106,6 +110,15 @@ template <class Type> bool AllAreInitialized(const Type& t) { return true; } +class ArenaString; + +// Read a length (varint32), followed by a string, from *input. Return a +// pointer to a copy of the string that resides in *arena. Requires both +// args to be non-NULL. If something goes wrong while reading the data +// then NULL is returned (e.g., input does not start with a valid varint). +ArenaString* ReadArenaString(::google::protobuf::io::CodedInputStream* input, + ::google::protobuf::Arena* arena); + } // namespace internal } // namespace protobuf diff --git a/src/google/protobuf/io/coded_stream.cc b/src/google/protobuf/io/coded_stream.cc index 93e1a22e..3b8650d6 100644 --- a/src/google/protobuf/io/coded_stream.cc +++ b/src/google/protobuf/io/coded_stream.cc @@ -156,6 +156,11 @@ CodedInputStream::IncrementRecursionDepthAndPushLimit(int byte_limit) { return std::make_pair(PushLimit(byte_limit), --recursion_budget_); } +CodedInputStream::Limit CodedInputStream::ReadLengthAndPushLimit() { + uint32 length; + return PushLimit(ReadVarint32(&length) ? length : 0); +} + bool CodedInputStream::DecrementRecursionDepthAndPopLimit(Limit limit) { bool result = ConsumedEntireMessage(); PopLimit(limit); @@ -164,6 +169,12 @@ bool CodedInputStream::DecrementRecursionDepthAndPopLimit(Limit limit) { 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(); @@ -245,20 +256,7 @@ bool CodedInputStream::GetDirectBufferPointer(const void** data, int* size) { } 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*>(buffer) + current_buffer_size; - size -= current_buffer_size; - Advance(current_buffer_size); - if (!Refresh()) return false; - } - - memcpy(buffer, buffer_, size); - Advance(size); - - return true; + return InternalReadRawInline(buffer, size); } bool CodedInputStream::ReadString(string* buffer, int size) { @@ -336,17 +334,23 @@ bool CodedInputStream::ReadLittleEndian64Fallback(uint64* value) { namespace { -inline const uint8* ReadVarint32FromArray( - const uint8* buffer, uint32* value) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; -inline const uint8* ReadVarint32FromArray(const uint8* buffer, uint32* value) { +// 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. +inline ::std::pair<bool, const uint8*> ReadVarint32FromArray( + uint32 first_byte, const uint8* buffer, + uint32* value) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; +inline ::std::pair<bool, const uint8*> ReadVarint32FromArray( + uint32 first_byte, const uint8* buffer, uint32* 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* ptr = buffer; uint32 b; - uint32 result; - - b = *(ptr++); result = b ; if (!(b & 0x80)) goto done; - result -= 0x80; + uint32 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; @@ -364,38 +368,42 @@ inline const uint8* ReadVarint32FromArray(const uint8* buffer, uint32* value) { // We have overrun the maximum size of a varint (10 bytes). Assume // the data is corrupt. - return NULL; + return std::make_pair(false, ptr); done: *value = result; - return ptr; + return std::make_pair(true, ptr); } } // namespace bool CodedInputStream::ReadVarint32Slow(uint32* value) { - uint64 result; // Directly invoke ReadVarint64Fallback, since we already tried to optimize // for one-byte varints. - if (!ReadVarint64Fallback(&result)) return false; - *value = (uint32)result; - return true; + std::pair<uint64, bool> p = ReadVarint64Fallback(); + *value = static_cast<uint32>(p.first); + return p.second; } -bool CodedInputStream::ReadVarint32Fallback(uint32* value) { +int64 CodedInputStream::ReadVarint32Fallback(uint32 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))) { - const uint8* end = ReadVarint32FromArray(buffer_, value); - if (end == NULL) return false; - buffer_ = end; - return true; + GOOGLE_DCHECK_NE(first_byte_or_zero, 0) + << "Caller should provide us with *buffer_ when buffer is non-empty"; + uint32 temp; + ::std::pair<bool, const uint8*> 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% - return ReadVarint32Slow(value); + uint32 temp; + return ReadVarint32Slow(&temp) ? static_cast<int64>(temp) : -1; } } @@ -425,18 +433,24 @@ uint32 CodedInputStream::ReadTagSlow() { return static_cast<uint32>(result); } -uint32 CodedInputStream::ReadTagFallback() { +uint32 CodedInputStream::ReadTagFallback(uint32 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 tag; - const uint8* end = ReadVarint32FromArray(buffer_, &tag); - if (end == NULL) { + ::std::pair<bool, const uint8*> p = + ReadVarint32FromArray(first_byte_or_zero, buffer_, &tag); + if (!p.first) { return 0; } - buffer_ = end; + buffer_ = p.second; return tag; } else { // We are commonly at a limit when attempting to read tags. Try to quickly @@ -479,7 +493,7 @@ bool CodedInputStream::ReadVarint64Slow(uint64* value) { return true; } -bool CodedInputStream::ReadVarint64Fallback(uint64* value) { +std::pair<uint64, 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. @@ -517,16 +531,18 @@ bool CodedInputStream::ReadVarint64Fallback(uint64* value) { // We have overrun the maximum size of a varint (10 bytes). The data // must be corrupt. - return false; + return std::make_pair(0, false); done: Advance(ptr - buffer_); - *value = (static_cast<uint64>(part0) ) | - (static_cast<uint64>(part1) << 28) | - (static_cast<uint64>(part2) << 56); - return true; + return std::make_pair((static_cast<uint64>(part0)) | + (static_cast<uint64>(part1) << 28) | + (static_cast<uint64>(part2) << 56), + true); } else { - return ReadVarint64Slow(value); + uint64 temp; + bool success = ReadVarint64Slow(&temp); + return std::make_pair(temp, success); } } diff --git a/src/google/protobuf/io/coded_stream.h b/src/google/protobuf/io/coded_stream.h index dea4b650..961c1a3f 100644 --- a/src/google/protobuf/io/coded_stream.h +++ b/src/google/protobuf/io/coded_stream.h @@ -197,6 +197,11 @@ class LIBPROTOBUF_EXPORT CodedInputStream { // Read raw bytes, copying them into the given buffer. bool ReadRaw(void* buffer, int size); + // Like the above, with inlined optimizations. This should only be used + // by the protobuf implementation. + inline bool InternalReadRawInline(void* buffer, + int size) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; + // Like ReadRaw, but reads into a string. // // Implementation Note: ReadString() grows the string gradually as it @@ -387,9 +392,14 @@ class LIBPROTOBUF_EXPORT CodedInputStream { // under the limit, false if it has gone over. bool IncrementRecursionDepth(); - // Decrements the recursion depth. + // 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 @@ -398,15 +408,25 @@ class LIBPROTOBUF_EXPORT CodedInputStream { 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); - // DecrementRecursionDepth(); + // 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. // @@ -568,9 +588,13 @@ class LIBPROTOBUF_EXPORT CodedInputStream { // 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. - bool ReadVarint32Fallback(uint32* value); - bool ReadVarint64Fallback(uint64* value); + // 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 it read otherwise. The latter has a bool + // indicating success or failure as part of its return type. + int64 ReadVarint32Fallback(uint32 first_byte_or_zero); + std::pair<uint64, bool> ReadVarint64Fallback(); bool ReadVarint32Slow(uint32* value); bool ReadVarint64Slow(uint64* value); bool ReadLittleEndian32Fallback(uint32* value); @@ -578,7 +602,7 @@ class LIBPROTOBUF_EXPORT CodedInputStream { // 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 ReadTagFallback(); + uint32 ReadTagFallback(uint32 first_byte_or_zero); uint32 ReadTagSlow(); bool ReadStringFallback(string* buffer, int size); @@ -818,13 +842,18 @@ class LIBPROTOBUF_EXPORT CodedOutputStream { // methods optimize for that case. inline bool CodedInputStream::ReadVarint32(uint32* value) { - if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_) && *buffer_ < 0x80) { - *value = *buffer_; - Advance(1); - return true; - } else { - return ReadVarint32Fallback(value); + uint32 v = 0; + if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_)) { + v = *buffer_; + if (v < 0x80) { + *value = v; + Advance(1); + return true; + } } + int64 result = ReadVarint32Fallback(v); + *value = static_cast<uint32>(result); + return result >= 0; } inline bool CodedInputStream::ReadVarint64(uint64* value) { @@ -832,9 +861,10 @@ inline bool CodedInputStream::ReadVarint64(uint64* value) { *value = *buffer_; Advance(1); return true; - } else { - return ReadVarint64Fallback(value); } + std::pair<uint64, bool> p = ReadVarint64Fallback(); + *value = p.first; + return p.second; } // static @@ -903,14 +933,17 @@ inline bool CodedInputStream::ReadLittleEndian64(uint64* value) { } inline uint32 CodedInputStream::ReadTag() { - if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_) && buffer_[0] < 0x80) { - last_tag_ = buffer_[0]; - Advance(1); - return last_tag_; - } else { - last_tag_ = ReadTagFallback(); - return last_tag_; + uint32 v = 0; + if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_)) { + v = *buffer_; + if (v < 0x80) { + last_tag_ = v; + Advance(1); + return v; + } } + last_tag_ = ReadTagFallback(v); + return last_tag_; } inline std::pair<uint32, bool> CodedInputStream::ReadTagWithCutoff( @@ -918,10 +951,12 @@ inline std::pair<uint32, bool> CodedInputStream::ReadTagWithCutoff( // 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 first_byte_or_zero = 0; if (GOOGLE_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>(buffer_[0]) > 0) { const uint32 kMax1ByteVarint = 0x7f; uint32 tag = last_tag_ = buffer_[0]; @@ -948,7 +983,7 @@ inline std::pair<uint32, bool> CodedInputStream::ReadTagWithCutoff( } } // Slow path - last_tag_ = ReadTagFallback(); + last_tag_ = ReadTagFallback(first_byte_or_zero); return std::make_pair(last_tag_, static_cast<uint32>(last_tag_ - 1) < cutoff); } @@ -1177,6 +1212,11 @@ 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; diff --git a/src/google/protobuf/io/coded_stream_inl.h b/src/google/protobuf/io/coded_stream_inl.h index cd8d1746..fa20f208 100644 --- a/src/google/protobuf/io/coded_stream_inl.h +++ b/src/google/protobuf/io/coded_stream_inl.h @@ -66,6 +66,23 @@ inline bool CodedInputStream::InternalReadStringInline(string* buffer, return ReadStringFallback(buffer, size); } +inline bool CodedInputStream::InternalReadRawInline(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*>(buffer) + current_buffer_size; + size -= current_buffer_size; + Advance(current_buffer_size); + if (!Refresh()) return false; + } + + memcpy(buffer, buffer_, size); + Advance(size); + + return true; +} + } // namespace io } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/io/printer.cc b/src/google/protobuf/io/printer.cc index e621ba1d..3ae8c268 100644 --- a/src/google/protobuf/io/printer.cc +++ b/src/google/protobuf/io/printer.cc @@ -155,6 +155,78 @@ void Printer::Print(const char* text, Print(vars, text); } +void Printer::Print(const char* text, + const char* variable1, const string& value1, + const char* variable2, const string& value2, + const char* variable3, const string& value3, + const char* variable4, const string& value4, + const char* variable5, const string& value5) { + map<string, string> vars; + vars[variable1] = value1; + vars[variable2] = value2; + vars[variable3] = value3; + vars[variable4] = value4; + vars[variable5] = value5; + Print(vars, text); +} + +void Printer::Print(const char* text, + const char* variable1, const string& value1, + const char* variable2, const string& value2, + const char* variable3, const string& value3, + const char* variable4, const string& value4, + const char* variable5, const string& value5, + const char* variable6, const string& value6) { + map<string, string> vars; + vars[variable1] = value1; + vars[variable2] = value2; + vars[variable3] = value3; + vars[variable4] = value4; + vars[variable5] = value5; + vars[variable6] = value6; + Print(vars, text); +} + +void Printer::Print(const char* text, + const char* variable1, const string& value1, + const char* variable2, const string& value2, + const char* variable3, const string& value3, + const char* variable4, const string& value4, + const char* variable5, const string& value5, + const char* variable6, const string& value6, + const char* variable7, const string& value7) { + map<string, string> vars; + vars[variable1] = value1; + vars[variable2] = value2; + vars[variable3] = value3; + vars[variable4] = value4; + vars[variable5] = value5; + vars[variable6] = value6; + vars[variable7] = value7; + Print(vars, text); +} + +void Printer::Print(const char* text, + const char* variable1, const string& value1, + const char* variable2, const string& value2, + const char* variable3, const string& value3, + const char* variable4, const string& value4, + const char* variable5, const string& value5, + const char* variable6, const string& value6, + const char* variable7, const string& value7, + const char* variable8, const string& value8) { + map<string, string> vars; + vars[variable1] = value1; + vars[variable2] = value2; + vars[variable3] = value3; + vars[variable4] = value4; + vars[variable5] = value5; + vars[variable6] = value6; + vars[variable7] = value7; + vars[variable8] = value8; + Print(vars, text); +} + void Printer::Indent() { indent_ += " "; } diff --git a/src/google/protobuf/io/printer.h b/src/google/protobuf/io/printer.h index 92ce3409..f1490bbe 100644 --- a/src/google/protobuf/io/printer.h +++ b/src/google/protobuf/io/printer.h @@ -91,8 +91,36 @@ class LIBPROTOBUF_EXPORT Printer { const char* variable2, const string& value2, const char* variable3, const string& value3, const char* variable4, const string& value4); - // TODO(kenton): Overloaded versions with more variables? Three seems - // to be enough. + // Like the first Print(), except the substitutions are given as parameters. + void Print(const char* text, const char* variable1, const string& value1, + const char* variable2, const string& value2, + const char* variable3, const string& value3, + const char* variable4, const string& value4, + const char* variable5, const string& value5); + // Like the first Print(), except the substitutions are given as parameters. + void Print(const char* text, const char* variable1, const string& value1, + const char* variable2, const string& value2, + const char* variable3, const string& value3, + const char* variable4, const string& value4, + const char* variable5, const string& value5, + const char* variable6, const string& value6); + // Like the first Print(), except the substitutions are given as parameters. + void Print(const char* text, const char* variable1, const string& value1, + const char* variable2, const string& value2, + const char* variable3, const string& value3, + const char* variable4, const string& value4, + const char* variable5, const string& value5, + const char* variable6, const string& value6, + const char* variable7, const string& value7); + // Like the first Print(), except the substitutions are given as parameters. + void Print(const char* text, const char* variable1, const string& value1, + const char* variable2, const string& value2, + const char* variable3, const string& value3, + const char* variable4, const string& value4, + const char* variable5, const string& value5, + const char* variable6, const string& value6, + const char* variable7, const string& value7, + const char* variable8, const string& value8); // 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 diff --git a/src/google/protobuf/lite_unittest.cc b/src/google/protobuf/lite_unittest.cc index 4ea21007..5af8b24d 100644 --- a/src/google/protobuf/lite_unittest.cc +++ b/src/google/protobuf/lite_unittest.cc @@ -34,12 +34,16 @@ #include <iostream> #include <google/protobuf/stubs/common.h> +#include <google/protobuf/arena_test_util.h> +#include <google/protobuf/map_lite_unittest.pb.h> +#include <google/protobuf/map_lite_test_util.h> #include <google/protobuf/test_util_lite.h> #include <google/protobuf/unittest_lite.pb.h> #include <google/protobuf/io/coded_stream.h> #include <google/protobuf/io/zero_copy_stream_impl_lite.h> #include <google/protobuf/wire_format_lite.h> #include <google/protobuf/wire_format_lite_inl.h> +#include <google/protobuf/stubs/strutil.h> using namespace std; @@ -84,6 +88,12 @@ void SetSomeTypesInEmptyMessageUnknownFields( } // namespace +#define EXPECT_TRUE GOOGLE_CHECK +#define ASSERT_TRUE GOOGLE_CHECK +#define EXPECT_FALSE(COND) GOOGLE_CHECK(!(COND)) +#define EXPECT_EQ GOOGLE_CHECK_EQ +#define ASSERT_EQ GOOGLE_CHECK_EQ + int main(int argc, char* argv[]) { string data, data2, packed_data; @@ -345,6 +355,374 @@ int main(int argc, char* argv[]) { GOOGLE_CHECK_EQ(0, empty_message.unknown_fields().size()); } + // Tests for map lite ============================================= + + { + // Accessors + protobuf_unittest::TestMapLite message; + + google::protobuf::MapLiteTestUtil::SetMapFields(&message); + google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message); + + google::protobuf::MapLiteTestUtil::ModifyMapFields(&message); + google::protobuf::MapLiteTestUtil::ExpectMapFieldsModified(message); + } + + { + // SetMapFieldsInitialized + protobuf_unittest::TestMapLite message; + + google::protobuf::MapLiteTestUtil::SetMapFieldsInitialized(&message); + google::protobuf::MapLiteTestUtil::ExpectMapFieldsSetInitialized(message); + } + + { + // Proto2SetMapFieldsInitialized + protobuf_unittest::TestEnumStartWithNonZeroMapLite message; + EXPECT_EQ(protobuf_unittest::PROTO2_NON_ZERO_MAP_ENUM_FOO_LITE, + (*message.mutable_map_field())[0]); + } + + { + // Clear + protobuf_unittest::TestMapLite message; + + google::protobuf::MapLiteTestUtil::SetMapFields(&message); + message.Clear(); + google::protobuf::MapLiteTestUtil::ExpectClear(message); + } + + { + // ClearMessageMap + protobuf_unittest::TestMessageMapLite message; + + // Creates a TestAllTypes with default value + google::protobuf::TestUtilLite::ExpectClear( + (*message.mutable_map_int32_message())[0]); + } + + { + // CopyFrom + protobuf_unittest::TestMapLite message1, message2; + + google::protobuf::MapLiteTestUtil::SetMapFields(&message1); + message2.CopyFrom(message1); + google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message2); + + // Copying from self should be a no-op. + message2.CopyFrom(message2); + google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message2); + } + + { + // 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)); + } + + { + // SwapWithEmpty + protobuf_unittest::TestMapLite message1, message2; + + google::protobuf::MapLiteTestUtil::SetMapFields(&message1); + google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message1); + google::protobuf::MapLiteTestUtil::ExpectClear(message2); + + message1.Swap(&message2); + google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message2); + google::protobuf::MapLiteTestUtil::ExpectClear(message1); + } + + { + // SwapWithSelf + protobuf_unittest::TestMapLite message; + + google::protobuf::MapLiteTestUtil::SetMapFields(&message); + google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message); + + message.Swap(&message); + google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message); + } + + { + // SwapWithOther + protobuf_unittest::TestMapLite message1, message2; + + google::protobuf::MapLiteTestUtil::SetMapFields(&message1); + google::protobuf::MapLiteTestUtil::SetMapFields(&message2); + google::protobuf::MapLiteTestUtil::ModifyMapFields(&message2); + + message1.Swap(&message2); + google::protobuf::MapLiteTestUtil::ExpectMapFieldsModified(message1); + google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message2); + } + + { + // CopyConstructor + protobuf_unittest::TestMapLite message1; + google::protobuf::MapLiteTestUtil::SetMapFields(&message1); + + protobuf_unittest::TestMapLite message2(message1); + google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message2); + } + + { + // CopyAssignmentOperator + protobuf_unittest::TestMapLite message1; + google::protobuf::MapLiteTestUtil::SetMapFields(&message1); + + protobuf_unittest::TestMapLite message2; + message2 = message1; + google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message2); + + // Make sure that self-assignment does something sane. + message2.operator=(message2); + google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message2); + } + + { + // NonEmptyMergeFrom + protobuf_unittest::TestMapLite message1, message2; + + google::protobuf::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); + google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message1); + } + + { + // 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 the generated SerializeWithCachedSizesToArray() + protobuf_unittest::TestMapLite message1, message2; + string data; + google::protobuf::MapLiteTestUtil::SetMapFields(&message1); + int size = message1.ByteSize(); + 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)); + google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message2); + } + + { + // Test the generated SerializeWithCachedSizes() + protobuf_unittest::TestMapLite message1, message2; + google::protobuf::MapLiteTestUtil::SetMapFields(&message1); + int size = message1.ByteSize(); + string data; + data.resize(size); + { + // Allow the output stream to buffer only one byte at a time. + google::protobuf::io::ArrayOutputStream array_stream( + ::google::protobuf::string_as_array(&data), size, 1); + google::protobuf::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)); + google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message2); + } + + + { + // 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; + 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()); + EXPECT_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)); + EXPECT_EQ(1, from.known_map_field().size()); + EXPECT_EQ(protobuf_unittest::E_PROTO2_MAP_ENUM_FOO_LITE, + from.known_map_field().at(0)); + EXPECT_EQ(1, from.unknown_map_field().size()); + EXPECT_EQ(protobuf_unittest::E_PROTO2_MAP_ENUM_EXTRA_LITE, + from.unknown_map_field().at(0)); + } + + { + // StandardWireFormat + protobuf_unittest::TestMapLite message; + 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)); + } + + { + // UnorderedWireFormat + protobuf_unittest::TestMapLite message; + + // put value before key in wire format + string data = "\x0A\x04\x10\x01\x08\x02"; + + EXPECT_TRUE(message.ParseFromString(data)); + EXPECT_EQ(1, message.map_int32_int32().size()); + EXPECT_EQ(1, message.map_int32_int32().at(2)); + } + + { + // DuplicatedKeyWireFormat + protobuf_unittest::TestMapLite message; + + // Two key fields in wire format + 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)); + } + + { + // DuplicatedValueWireFormat + protobuf_unittest::TestMapLite message; + + // Two value fields in wire format + 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)); + } + + { + // MissedKeyWireFormat + protobuf_unittest::TestMapLite message; + + // No key field in wire format + string data = "\x0A\x02\x10\x01"; + + EXPECT_TRUE(message.ParseFromString(data)); + EXPECT_EQ(1, message.map_int32_int32().size()); + EXPECT_EQ(1, message.map_int32_int32().at(0)); + } + + { + // MissedValueWireFormat + protobuf_unittest::TestMapLite message; + + // No value field in wire format + string data = "\x0A\x02\x08\x01"; + + EXPECT_TRUE(message.ParseFromString(data)); + EXPECT_EQ(1, message.map_int32_int32().size()); + EXPECT_EQ(0, message.map_int32_int32().at(1)); + } + + { + // UnknownFieldWireFormat + protobuf_unittest::TestMapLite message; + + // Unknown field in wire format + 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)); + } + + { + // CorruptedWireFormat + protobuf_unittest::TestMapLite message; + + // corrupted data in wire format + string data = "\x0A\x06\x08\x02\x11\x03"; + + EXPECT_FALSE(message.ParseFromString(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()); + } + + // arena support for map ========================================= + + { + // ParsingAndSerializingNoHeapAllocation + + // Allocate a large initial block to avoid mallocs during hooked test. + std::vector<char> arena_block(128 * 1024); + google::protobuf::ArenaOptions options; + options.initial_block = &arena_block[0]; + options.initial_block_size = arena_block.size(); + google::protobuf::Arena arena(options); + string data; + data.reserve(128 * 1024); + + { + google::protobuf::internal::NoHeapChecker no_heap; + + protobuf_unittest::TestArenaMapLite* from = + google::protobuf::Arena::CreateMessage<protobuf_unittest::TestArenaMapLite>( + &arena); + google::protobuf::MapLiteTestUtil::SetArenaMapFields(from); + from->SerializeToString(&data); + + protobuf_unittest::TestArenaMapLite* to = + google::protobuf::Arena::CreateMessage<protobuf_unittest::TestArenaMapLite>( + &arena); + to->ParseFromString(data); + google::protobuf::MapLiteTestUtil::ExpectArenaMapFieldsSet(*to); + } + } + std::cout << "PASS" << std::endl; return 0; } diff --git a/src/google/protobuf/map.h b/src/google/protobuf/map.h index e56af3fc..c16fbed2 100644 --- a/src/google/protobuf/map.h +++ b/src/google/protobuf/map.h @@ -33,6 +33,7 @@ #include <iterator> #include <google/protobuf/stubs/hash.h> +#include <limits> // To support Visual Studio 2008 #include <google/protobuf/arena.h> #include <google/protobuf/generated_enum_util.h> @@ -167,11 +168,23 @@ class Map { } } +#if __cplusplus >= 201103L && !defined(GOOGLE_PROTOBUF_OS_APPLE) + template<class NodeType, class... Args> + void construct(NodeType* p, Args&&... args) { + new (p) NodeType(std::forward<Args>(args)...); + } + + template<class NodeType> + void destroy(NodeType* p) { + if (arena_ == NULL) p->~NodeType(); + } +#else void construct(pointer p, const_reference t) { new (p) value_type(t); } void destroy(pointer p) { if (arena_ == NULL) p->~value_type(); } +#endif template <typename X> struct rebind { @@ -188,6 +201,11 @@ class Map { return arena_ != other.arena_; } + // To support Visual Studio 2008 + size_type max_size() const { + return std::numeric_limits<size_type>::max(); + } + private: Arena* arena_; @@ -199,7 +217,7 @@ class Map { typedef MapAllocator<std::pair<const Key, MapPair<Key, T>*> > Allocator; // Iterators - class LIBPROTOBUF_EXPORT const_iterator + class const_iterator : public std::iterator<std::forward_iterator_tag, value_type, ptrdiff_t, const value_type*, const value_type&> { typedef typename hash_map<Key, value_type*, hash<Key>, equal_to<Key>, @@ -229,7 +247,7 @@ class Map { InnerIt it_; }; - class LIBPROTOBUF_EXPORT iterator : public std::iterator<std::forward_iterator_tag, value_type> { + class iterator : public std::iterator<std::forward_iterator_tag, value_type> { typedef typename hash_map<Key, value_type*, hasher, equal_to<Key>, Allocator>::iterator InnerIt; @@ -422,12 +440,13 @@ class Map { int default_enum_value_; friend class ::google::protobuf::Arena; + typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; template <typename K, typename V, internal::WireFormatLite::FieldType key_wire_type, internal::WireFormatLite::FieldType value_wire_type, int default_enum_value> - friend class LIBPROTOBUF_EXPORT internal::MapFieldLite; + friend class internal::MapFieldLite; }; } // namespace protobuf diff --git a/src/google/protobuf/map_entry.h b/src/google/protobuf/map_entry.h index f78a4f40..e93d0348 100644 --- a/src/google/protobuf/map_entry.h +++ b/src/google/protobuf/map_entry.h @@ -97,7 +97,7 @@ template <typename Key, typename Value, WireFormatLite::FieldType kKeyFieldType, WireFormatLite::FieldType kValueFieldType, int default_enum_value> -class LIBPROTOBUF_EXPORT MapEntry : public MapEntryBase { +class MapEntry : public MapEntryBase { // Handlers for key/value wire type. Provide utilities to parse/serialize // key/value. typedef MapWireFieldTypeHandler<kKeyFieldType> KeyWireHandler; @@ -274,8 +274,8 @@ class LIBPROTOBUF_EXPORT MapEntry : public MapEntryBase { typedef void DestructorSkippable_; template <typename K, typename V, WireFormatLite::FieldType k_wire_type, WireFormatLite::FieldType, int default_enum> - friend class LIBPROTOBUF_EXPORT internal::MapField; - friend class LIBPROTOBUF_EXPORT internal::GeneratedMessageReflection; + friend class internal::MapField; + friend class internal::GeneratedMessageReflection; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntry); }; diff --git a/src/google/protobuf/map_entry_lite.h b/src/google/protobuf/map_entry_lite.h index 304fba88..52746da5 100644 --- a/src/google/protobuf/map_entry_lite.h +++ b/src/google/protobuf/map_entry_lite.h @@ -60,7 +60,7 @@ template <typename Key, typename Value, WireFormatLite::FieldType kKeyFieldType, WireFormatLite::FieldType kValueFieldType, int default_enum_value> -class LIBPROTOBUF_EXPORT MapEntryLite : public MessageLite { +class MapEntryLite : public MessageLite { // Handlers for key/value wire type. Provide utilities to parse/serialize // key/value. typedef MapWireFieldTypeHandler<kKeyFieldType> KeyWireHandler; @@ -267,17 +267,18 @@ class LIBPROTOBUF_EXPORT MapEntryLite : public MessageLite { // google::protobuf::Map is enum. We cannot create a reference to int from an enum. static MapEntryLite* EnumWrap(const Key& key, const Value value, Arena* arena) { - return Arena::Create<MapEnumEntryWrapper< + return Arena::CreateMessage<MapEnumEntryWrapper< Key, Value, kKeyFieldType, kValueFieldType, default_enum_value> >( - arena, key, value, arena); + arena, key, value); } // Like above, but for all the other types. This avoids value copy to create // MapEntryLite from google::protobuf::Map in serialization. static MapEntryLite* Wrap(const Key& key, const Value& value, Arena* arena) { - return Arena::Create<MapEntryWrapper<Key, Value, kKeyFieldType, - kValueFieldType, default_enum_value> >( - arena, key, value, arena); + return Arena::CreateMessage<MapEntryWrapper<Key, Value, kKeyFieldType, + kValueFieldType, + default_enum_value> >( + arena, key, value); } protected: @@ -301,14 +302,14 @@ class LIBPROTOBUF_EXPORT MapEntryLite : public MessageLite { // only takes references of given key and value. template <typename K, typename V, WireFormatLite::FieldType k_wire_type, WireFormatLite::FieldType v_wire_type, int default_enum> - class LIBPROTOBUF_EXPORT MapEntryWrapper + class MapEntryWrapper : public MapEntryLite<K, V, k_wire_type, v_wire_type, default_enum> { typedef MapEntryLite<K, V, k_wire_type, v_wire_type, default_enum> Base; typedef typename Base::KeyCppType KeyCppType; typedef typename Base::ValCppType ValCppType; public: - MapEntryWrapper(const K& key, const V& value, Arena* arena) + MapEntryWrapper(Arena* arena, const K& key, const V& value) : MapEntryLite<K, V, k_wire_type, v_wire_type, default_enum>(arena), key_(key), value_(value) { @@ -323,6 +324,7 @@ class LIBPROTOBUF_EXPORT MapEntryLite : public MessageLite { const Value& value_; friend class ::google::protobuf::Arena; + typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; }; @@ -334,14 +336,14 @@ class LIBPROTOBUF_EXPORT MapEntryLite : public MessageLite { // the temporary. template <typename K, typename V, WireFormatLite::FieldType k_wire_type, WireFormatLite::FieldType v_wire_type, int default_enum> - class LIBPROTOBUF_EXPORT MapEnumEntryWrapper + class MapEnumEntryWrapper : public MapEntryLite<K, V, k_wire_type, v_wire_type, default_enum> { typedef MapEntryLite<K, V, k_wire_type, v_wire_type, default_enum> Base; typedef typename Base::KeyCppType KeyCppType; typedef typename Base::ValCppType ValCppType; public: - MapEnumEntryWrapper(const K& key, const V& value, Arena* arena) + MapEnumEntryWrapper(Arena* arena, const K& key, const V& value) : MapEntryLite<K, V, k_wire_type, v_wire_type, default_enum>(arena), key_(key), value_(value) { @@ -355,7 +357,7 @@ class LIBPROTOBUF_EXPORT MapEntryLite : public MessageLite { const KeyCppType& key_; const ValCppType value_; - friend class ::google::protobuf::Arena; + friend class google::protobuf::Arena; typedef void DestructorSkippable_; }; @@ -394,10 +396,10 @@ class LIBPROTOBUF_EXPORT MapEntryLite : public MessageLite { typedef void DestructorSkippable_; template <typename K, typename V, WireFormatLite::FieldType, WireFormatLite::FieldType, int> - friend class LIBPROTOBUF_EXPORT internal::MapEntry; + friend class internal::MapEntry; template <typename K, typename V, WireFormatLite::FieldType, WireFormatLite::FieldType, int> - friend class LIBPROTOBUF_EXPORT internal::MapFieldLite; + friend class internal::MapFieldLite; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntryLite); }; diff --git a/src/google/protobuf/map_field.cc b/src/google/protobuf/map_field.cc index fd40c0d8..6ff1936e 100644 --- a/src/google/protobuf/map_field.cc +++ b/src/google/protobuf/map_field.cc @@ -104,14 +104,18 @@ void MapFieldBase::SetRepeatedDirty() { state_ = STATE_MODIFIED_REPEATED; } void* MapFieldBase::MutableRepeatedPtrField() const { return repeated_field_; } void MapFieldBase::SyncRepeatedFieldWithMap() const { - Atomic32 state = google::protobuf::internal::NoBarrier_Load(&state_); + // "Acquire" insures the operation after SyncRepeatedFieldWithMap won't get + // executed before state_ is checked. + Atomic32 state = google::protobuf::internal::Acquire_Load(&state_); if (state == 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_ == STATE_MODIFIED_MAP) { SyncRepeatedFieldWithMapNoLock(); - google::protobuf::internal::NoBarrier_Store(&state_, CLEAN); + // "Release" insures state_ can only be changed "after" + // SyncRepeatedFieldWithMapNoLock is finished. + google::protobuf::internal::Release_Store(&state_, CLEAN); } mutex_.Unlock(); } @@ -119,19 +123,23 @@ void MapFieldBase::SyncRepeatedFieldWithMap() const { void MapFieldBase::SyncRepeatedFieldWithMapNoLock() const { if (repeated_field_ == NULL) { - repeated_field_ = Arena::Create<RepeatedPtrField<Message> >(arena_, arena_); + repeated_field_ = Arena::CreateMessage<RepeatedPtrField<Message> >(arena_); } } void MapFieldBase::SyncMapWithRepeatedField() const { - Atomic32 state = google::protobuf::internal::NoBarrier_Load(&state_); + // "Acquire" insures the operation after SyncMapWithRepeatedField won't get + // executed before state_ is checked. + Atomic32 state = google::protobuf::internal::Acquire_Load(&state_); if (state == 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_ == STATE_MODIFIED_REPEATED) { SyncMapWithRepeatedFieldNoLock(); - google::protobuf::internal::NoBarrier_Store(&state_, CLEAN); + // "Release" insures state_ can only be changed "after" + // SyncRepeatedFieldWithMapNoLock is finished. + google::protobuf::internal::Release_Store(&state_, CLEAN); } mutex_.Unlock(); } diff --git a/src/google/protobuf/map_field.h b/src/google/protobuf/map_field.h index 6d8b6ec8..56d3d0f4 100644 --- a/src/google/protobuf/map_field.h +++ b/src/google/protobuf/map_field.h @@ -68,7 +68,11 @@ class LIBPROTOBUF_EXPORT MapFieldBase { repeated_field_(NULL), entry_descriptor_(NULL), assign_descriptor_callback_(NULL), - state_(STATE_MODIFIED_MAP) {} + state_(STATE_MODIFIED_MAP) { + // Mutex's destructor needs to be called explicitly to release resources + // acquired in its constructor. + arena->OwnDestructor(&mutex_); + } virtual ~MapFieldBase(); // Returns reference to internal repeated field. Data written using @@ -146,7 +150,7 @@ template <typename Key, typename T, WireFormatLite::FieldType kKeyFieldType, WireFormatLite::FieldType kValueFieldType, int default_enum_value = 0> -class LIBPROTOBUF_EXPORT MapField : public MapFieldBase, +class MapField : public MapFieldBase, public MapFieldLite<Key, T, kKeyFieldType, kValueFieldType, default_enum_value> { // Handlers for key/value wire type. Provide utilities to parse/serialize @@ -208,6 +212,7 @@ class LIBPROTOBUF_EXPORT MapField : public MapFieldBase, void SetAssignDescriptorCallback(void (*callback)()); private: + typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; // MapField needs MapEntry's default instance to create new MapEntry. diff --git a/src/google/protobuf/map_field_inl.h b/src/google/protobuf/map_field_inl.h index ae63c721..5b4305f9 100644 --- a/src/google/protobuf/map_field_inl.h +++ b/src/google/protobuf/map_field_inl.h @@ -212,11 +212,11 @@ void MapField<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>::SyncRepeatedFieldWithMapNoLock() const { if (repeated_field_ == NULL) { - if (arena_ == NULL) { + if (MapFieldBase::arena_ == NULL) { repeated_field_ = new RepeatedPtrField<Message>(); } else { - repeated_field_ = - Arena::Create<RepeatedPtrField<Message> >(arena_, arena_); + repeated_field_ = Arena::CreateMessage<RepeatedPtrField<Message> >( + MapFieldBase::arena_); } } const Map<Key, T>& map = GetInternalMap(); @@ -229,7 +229,8 @@ MapField<Key, T, kKeyFieldType, kValueFieldType, it != map.end(); ++it) { InitDefaultEntryOnce(); GOOGLE_CHECK(default_entry_ != NULL); - EntryType* new_entry = down_cast<EntryType*>(default_entry_->New(arena_)); + EntryType* new_entry = + down_cast<EntryType*>(default_entry_->New(MapFieldBase::arena_)); repeated_field->AddAllocated(new_entry); (*new_entry->mutable_key()) = it->first; (*new_entry->mutable_value()) = it->second; diff --git a/src/google/protobuf/map_field_lite.h b/src/google/protobuf/map_field_lite.h index 549ecc08..860dae55 100644 --- a/src/google/protobuf/map_field_lite.h +++ b/src/google/protobuf/map_field_lite.h @@ -45,7 +45,7 @@ template <typename Key, typename T, WireFormatLite::FieldType key_wire_type, WireFormatLite::FieldType value_wire_type, int default_enum_value = 0> -class LIBPROTOBUF_EXPORT MapFieldLite { +class MapFieldLite { // Define message type for internal repeated field. typedef MapEntryLite<Key, T, key_wire_type, value_wire_type, default_enum_value> EntryType; @@ -109,7 +109,7 @@ template <typename Key, typename T, MapFieldLite<Key, T, key_wire_type, value_wire_type, default_enum_value>::MapFieldLite(Arena* arena) : arena_(arena) { - map_ = Arena::Create<Map<Key, T> >(arena, arena); + map_ = Arena::CreateMessage<Map<Key, T> >(arena); SetDefaultEnumValue(); } diff --git a/src/google/protobuf/map_field_test.cc b/src/google/protobuf/map_field_test.cc index 61344cbb..e3a64079 100644 --- a/src/google/protobuf/map_field_test.cc +++ b/src/google/protobuf/map_field_test.cc @@ -56,6 +56,7 @@ using unittest::TestAllTypes; class MapFieldBaseStub : public MapFieldBase { public: + typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; MapFieldBaseStub() {} explicit MapFieldBaseStub(Arena* arena) : MapFieldBase(arena) {} @@ -144,15 +145,17 @@ TEST_F(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.data(); + options.initial_block = &arena_block[0]; options.initial_block_size = arena_block.size(); Arena arena(options); { - NoHeapChecker no_heap; + // 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::Create<MapFieldType>(&arena, &arena, default_entry_); + Arena::CreateMessage<MapFieldType>(&arena, default_entry_); // Set content in map (*map_field->MutableMap())[100] = 101; @@ -162,10 +165,12 @@ TEST_F(MapFieldBasePrimitiveTest, Arena) { } { - NoHeapChecker no_heap; + // 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::Create<MapFieldBaseStub>(&arena, &arena); + Arena::CreateMessage<MapFieldBaseStub>(&arena); // Trigger conversion to repeated field. EXPECT_TRUE(map_field->MutableRepeatedField() != NULL); diff --git a/src/google/protobuf/map_lite_unittest.proto b/src/google/protobuf/map_lite_unittest.proto index c69e8d94..febfe5f6 100644 --- a/src/google/protobuf/map_lite_unittest.proto +++ b/src/google/protobuf/map_lite_unittest.proto @@ -32,6 +32,7 @@ syntax = "proto2"; option cc_enable_arenas = true; option optimize_for = LITE_RUNTIME; +option csharp_namespace = "Google.ProtocolBuffers.TestProtos"; import "google/protobuf/unittest_lite.proto"; diff --git a/src/google/protobuf/map_proto2_unittest.proto b/src/google/protobuf/map_proto2_unittest.proto index 3d4af28e..04ca6170 100644 --- a/src/google/protobuf/map_proto2_unittest.proto +++ b/src/google/protobuf/map_proto2_unittest.proto @@ -36,6 +36,8 @@ syntax = "proto2"; // In map_test_util.h we do "using namespace unittest = protobuf_unittest". package protobuf_unittest; +option csharp_namespace = "Google.ProtocolBuffers.TestProtos"; + enum Proto2MapEnum { PROTO2_MAP_ENUM_FOO = 0; PROTO2_MAP_ENUM_BAR = 1; diff --git a/src/google/protobuf/map_test.cc b/src/google/protobuf/map_test.cc index 88cba1f2..d62ec85f 100644 --- a/src/google/protobuf/map_test.cc +++ b/src/google/protobuf/map_test.cc @@ -2258,13 +2258,34 @@ TEST(TextFormatMapTest, SerializeAndParse) { MapTestUtil::ExpectMapFieldsSet(dest); } +TEST(TextFormatMapTest, Sorted) { + unittest::TestMap message; + MapTestUtil::MapReflectionTester tester(message.GetDescriptor()); + tester.SetMapFieldsViaReflection(&message); + + string expected_text; + GOOGLE_CHECK_OK(File::GetContents( + TestSourceDir() + + "/google/protobuf/" + "testdata/map_test_data.txt", + &expected_text, true)); + + 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); +} + // 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.data(); + options.initial_block = &arena_block[0]; options.initial_block_size = arena_block.size(); Arena arena(options); string data; diff --git a/src/google/protobuf/map_type_handler.h b/src/google/protobuf/map_type_handler.h index 278b78ae..ffdb6dfb 100644 --- a/src/google/protobuf/map_type_handler.h +++ b/src/google/protobuf/map_type_handler.h @@ -129,11 +129,11 @@ class MapCppTypeHandler : public MapCommonTypeHandler<Type> { // Return bytes used by value in Map. static int SpaceUsedInMap(const Type& value) { return value.SpaceUsed(); } static inline void Clear(Type** value) { - if (*value != NULL) (*value)->Type::Clear(); + if (*value != NULL) (*value)->Clear(); } static inline void ClearMaybeByDefaultEnum(Type** value, int default_enum_value) { - if (*value != NULL) (*value)->Type::Clear(); + if (*value != NULL) (*value)->Clear(); } static inline void Merge(const Type& from, Type** to) { (*to)->MergeFrom(from); diff --git a/src/google/protobuf/map_unittest.proto b/src/google/protobuf/map_unittest.proto index 830f672b..cbf747d9 100644 --- a/src/google/protobuf/map_unittest.proto +++ b/src/google/protobuf/map_unittest.proto @@ -31,6 +31,7 @@ syntax = "proto3"; option cc_enable_arenas = true; +option csharp_namespace = "Google.ProtocolBuffers.TestProtos"; import "google/protobuf/unittest.proto"; @@ -61,7 +62,7 @@ message TestMap { } message TestMapSubmessage { - optional TestMap test_map = 1; + TestMap test_map = 1; } message TestMessageMap { @@ -103,3 +104,17 @@ message TestArenaMap { map<int32 , MapEnum > map_int32_enum = 14; map<int32 , ForeignMessage> map_int32_foreign_message = 15; } + +// Previously, message containing enum called Type cannot be used as value of +// map field. +message MessageContainingEnumCalledType { + enum Type { + TYPE_FOO = 0; + } + map<int32, MessageContainingEnumCalledType> type = 1; +} + +// Previously, message cannot contain map field called "entry". +message MessageContainingMapCalledEntry { + map<int32, int32> entry = 1; +} diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc index f58be848..276d7de5 100644 --- a/src/google/protobuf/message.cc +++ b/src/google/protobuf/message.cc @@ -465,10 +465,21 @@ struct ShutdownRepeatedFieldRegister { } // namespace internal namespace internal { -// Macro defined in repeated_field.h. We can only define the Message-specific -// GenericTypeHandler specializations here because we depend on Message, which -// is not part of proto2-lite hence is not available in repeated_field.h. -DEFINE_SPECIALIZATIONS_FOR_BASE_PROTO_TYPES_NOINLINE(Message); +template<> +Message* GenericTypeHandler<Message>::NewFromPrototype( + const Message* prototype, google::protobuf::Arena* arena) { + return prototype->New(arena); +} +template<> +google::protobuf::Arena* GenericTypeHandler<Message>::GetArena( + Message* value) { + return value->GetArena(); +} +template<> +void* GenericTypeHandler<Message>::GetMaybeArenaPointer( + Message* value) { + return value->GetMaybeArenaPointer(); +} } // namespace internal } // namespace protobuf diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h index 6e1929e5..18c092d0 100644 --- a/src/google/protobuf/message.h +++ b/src/google/protobuf/message.h @@ -98,11 +98,11 @@ // // // 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); +// 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; // } @@ -229,6 +229,11 @@ class LIBPROTOBUF_EXPORT Message : public MessageLite { // 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 int SpaceUsed() const; // Debugging & Testing---------------------------------------------- diff --git a/src/google/protobuf/message_lite.cc b/src/google/protobuf/message_lite.cc index 63be0e9b..4f63ad2b 100644 --- a/src/google/protobuf/message_lite.cc +++ b/src/google/protobuf/message_lite.cc @@ -337,7 +337,7 @@ bool MessageLite::SerializePartialToArray(void* data, int size) const { string MessageLite::SerializeAsString() const { // If the compiler implements the (Named) Return Value Optimization, - // the local variable 'result' will not actually reside on the stack + // 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. string output; diff --git a/src/google/protobuf/message_lite.h b/src/google/protobuf/message_lite.h index eab61c14..4c16f4c0 100644 --- a/src/google/protobuf/message_lite.h +++ b/src/google/protobuf/message_lite.h @@ -238,6 +238,9 @@ class LIBPROTOBUF_EXPORT MessageLite { // Computes the serialized size of the message. This recursively calls // ByteSize() on all embedded messages. If a subclass does not override // this, it MUST override SetCachedSize(). + // + // ByteSize() is generally linear in the number of fields defined for the + // proto. virtual int ByteSize() const = 0; // Serializes the message without recomputing the size. The message must diff --git a/src/google/protobuf/message_unittest.cc b/src/google/protobuf/message_unittest.cc index ebfb4321..75d60b8b 100644 --- a/src/google/protobuf/message_unittest.cc +++ b/src/google/protobuf/message_unittest.cc @@ -45,12 +45,13 @@ #include <sstream> #include <fstream> -#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/test_util.h> +#include <google/protobuf/unittest.pb.h> #include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/descriptor.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> #include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/unittest.pb.h> -#include <google/protobuf/test_util.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/generated_message_reflection.h> #include <google/protobuf/stubs/common.h> #include <google/protobuf/testing/googletest.h> @@ -205,6 +206,28 @@ TEST(MessageTest, InitializationErrorString) { EXPECT_EQ("a, b, c", message.InitializationErrorString()); } +TEST(MessageTest, DynamicCastToGenerated) { + unittest::TestAllTypes test_all_types; + + google::protobuf::Message* test_all_types_pointer = &test_all_types; + EXPECT_EQ(&test_all_types, + google::protobuf::internal::DynamicCastToGenerated<unittest::TestAllTypes>( + test_all_types_pointer)); + EXPECT_EQ(NULL, + google::protobuf::internal::DynamicCastToGenerated<unittest::TestRequired>( + test_all_types_pointer)); + + const google::protobuf::Message* test_all_types_pointer_const = &test_all_types; + EXPECT_EQ( + &test_all_types, + google::protobuf::internal::DynamicCastToGenerated<const unittest::TestAllTypes>( + test_all_types_pointer_const)); + EXPECT_EQ( + NULL, + google::protobuf::internal::DynamicCastToGenerated<const unittest::TestRequired>( + test_all_types_pointer_const)); +} + #ifdef PROTOBUF_HAS_DEATH_TEST // death tests do not work on Windows yet. TEST(MessageTest, SerializeFailsIfNotInitialized) { diff --git a/src/google/protobuf/preserve_unknown_enum_test.cc b/src/google/protobuf/preserve_unknown_enum_test.cc index 9f8703ae..1673e8af 100644 --- a/src/google/protobuf/preserve_unknown_enum_test.cc +++ b/src/google/protobuf/preserve_unknown_enum_test.cc @@ -246,8 +246,6 @@ TEST(PreserveUnknownEnumTest, Proto2CatchesUnknownValues) { protobuf_unittest::TestAllTypes message; // proto2 message const google::protobuf::Reflection* r = message.GetReflection(); const google::protobuf::Descriptor* d = message.GetDescriptor(); - const google::protobuf::FieldDescriptor* singular_field = - d->FindFieldByName("optional_nested_enum"); const google::protobuf::FieldDescriptor* repeated_field = d->FindFieldByName("repeated_nested_enum"); // Add one element to the repeated field so that we can test @@ -258,6 +256,8 @@ TEST(PreserveUnknownEnumTest, Proto2CatchesUnknownValues) { r->AddEnum(&message, repeated_field, enum_value); #ifdef PROTOBUF_HAS_DEATH_TEST + const google::protobuf::FieldDescriptor* singular_field = + d->FindFieldByName("optional_nested_enum"); // Enum-field integer-based setters GOOGLE_DCHECK-fail on invalid values, in order to // remain consistent with proto2 generated code. EXPECT_DEBUG_DEATH({ diff --git a/src/google/protobuf/proto3_arena_unittest.cc b/src/google/protobuf/proto3_arena_unittest.cc index c3b5996f..da4be673 100644 --- a/src/google/protobuf/proto3_arena_unittest.cc +++ b/src/google/protobuf/proto3_arena_unittest.cc @@ -180,6 +180,16 @@ TEST(ArenaTest, ReleaseMessage) { EXPECT_EQ(118, nested->bb()); } +TEST(ArenaTest, MessageFieldClear) { + // GitHub issue #310: https://github.com/google/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(); +} + } // namespace } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/reflection.h b/src/google/protobuf/reflection.h index 03c761c1..4ff0f6b4 100755 --- a/src/google/protobuf/reflection.h +++ b/src/google/protobuf/reflection.h @@ -39,6 +39,7 @@ #endif #include <google/protobuf/message.h> +#include <google/protobuf/generated_enum_util.h> namespace google { namespace protobuf { diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h index f5f5d3f4..5a2fb409 100644 --- a/src/google/protobuf/repeated_field.h +++ b/src/google/protobuf/repeated_field.h @@ -576,26 +576,21 @@ class GenericTypeHandler { } }; -// Macros for specializing GenericTypeHandler for base proto types, these are -// are defined here, to allow inlining them at their callsites. -#define DEFINE_SPECIALIZATIONS_FOR_BASE_PROTO_TYPES(Inline, TypeName) \ - template<> \ - Inline TypeName* GenericTypeHandler<TypeName>::NewFromPrototype( \ - const TypeName* prototype, google::protobuf::Arena* arena) { \ - return prototype->New(arena); \ - } \ - template<> \ - Inline google::protobuf::Arena* GenericTypeHandler<TypeName>::GetArena( \ - TypeName* value) { \ - return value->GetArena(); \ - } \ - template<> \ - Inline void* GenericTypeHandler<TypeName>::GetMaybeArenaPointer( \ - TypeName* value) { \ - return value->GetMaybeArenaPointer(); \ - } -#define DEFINE_SPECIALIZATIONS_FOR_BASE_PROTO_TYPES_NOINLINE(TypeName) \ - DEFINE_SPECIALIZATIONS_FOR_BASE_PROTO_TYPES(, TypeName) +template<> +inline MessageLite* GenericTypeHandler<MessageLite>::NewFromPrototype( + const MessageLite* prototype, google::protobuf::Arena* arena) { + return prototype->New(arena); +} +template<> +inline google::protobuf::Arena* GenericTypeHandler<MessageLite>::GetArena( + MessageLite* value) { + return value->GetArena(); +} +template<> +inline void* GenericTypeHandler<MessageLite>::GetMaybeArenaPointer( + MessageLite* value) { + return value->GetMaybeArenaPointer(); +} // Implements GenericTypeHandler specialization required by RepeatedPtrFields // to work with MessageLite type. @@ -605,8 +600,6 @@ inline void GenericTypeHandler<MessageLite>::Merge( to->CheckTypeAndMergeFrom(from); } -DEFINE_SPECIALIZATIONS_FOR_BASE_PROTO_TYPES(inline, MessageLite); - // Declarations of the specialization as we cannot define them here, as the // header that defines ProtocolMessage depends on types defined in this header. #define DECLARE_SPECIALIZATIONS_FOR_BASE_PROTO_TYPES(TypeName) \ @@ -626,7 +619,7 @@ DEFINE_SPECIALIZATIONS_FOR_BASE_PROTO_TYPES(inline, MessageLite); DECLARE_SPECIALIZATIONS_FOR_BASE_PROTO_TYPES(Message); -#undef DECLARE_SPECIALIZATIONS_FOR_BASE_CLASSES +#undef DECLARE_SPECIALIZATIONS_FOR_BASE_PROTO_TYPES template <> inline const MessageLite& GenericTypeHandler<MessageLite>::default_instance() { @@ -1235,6 +1228,7 @@ void RepeatedField<Element>::Reserve(int new_size) { kRepHeaderSize + sizeof(Element)*new_size)); } rep_->arena = arena; + int old_total_size = total_size_; total_size_ = new_size; // 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 @@ -1253,15 +1247,17 @@ void RepeatedField<Element>::Reserve(int new_size) { if (current_size_ > 0) { MoveArray(rep_->elements, old_rep->elements, current_size_); } - // Likewise, we need to invoke destructors on the old array. If Element has no - // destructor, this loop will disappear. - e = &old_rep->elements[0]; - limit = &old_rep->elements[current_size_]; - for (; e < limit; e++) { - e->Element::~Element(); - } - if (arena == NULL) { - delete[] reinterpret_cast<char*>(old_rep); + if (old_rep) { + // Likewise, we need to invoke destructors on the old array. If Element has + // no destructor, this loop will disappear. + e = &old_rep->elements[0]; + limit = &old_rep->elements[old_total_size]; + for (; e < limit; e++) { + e->Element::~Element(); + } + if (arena == NULL) { + delete[] reinterpret_cast<char*>(old_rep); + } } } @@ -1418,7 +1414,7 @@ void RepeatedPtrFieldBase::Clear() { const int n = current_size_; GOOGLE_DCHECK_GE(n, 0); if (n > 0) { - void* const* elements = raw_data(); + void* const* elements = rep_->elements; int i = 0; do { TypeHandler::Clear(cast<TypeHandler>(elements[i++])); diff --git a/src/google/protobuf/repeated_field_unittest.cc b/src/google/protobuf/repeated_field_unittest.cc index 66e74523..af397932 100644 --- a/src/google/protobuf/repeated_field_unittest.cc +++ b/src/google/protobuf/repeated_field_unittest.cc @@ -456,6 +456,28 @@ TEST(RepeatedField, ExtractSubrange) { } } +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<string> field; + for (int i = 0; i < 32; i++) { + field.Add(string("abcdefghijklmnopqrstuvwxyz0123456789")); + } + EXPECT_EQ(32, field.size()); + field.Clear(); + EXPECT_EQ(0, field.size()); + EXPECT_EQ(32, field.Capacity()); + + field.Reserve(1024); + EXPECT_EQ(0, field.size()); + EXPECT_EQ(1024, field.Capacity()); + // Finish test -- |field| should destroy the cleared-but-not-yet-destroyed + // strings. +} + // =================================================================== // RepeatedPtrField tests. These pretty much just mirror the RepeatedField // tests above. diff --git a/src/google/protobuf/source_context.pb.cc b/src/google/protobuf/source_context.pb.cc new file mode 100644 index 00000000..3b3799a9 --- /dev/null +++ b/src/google/protobuf/source_context.pb.cc @@ -0,0 +1,386 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/source_context.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "google/protobuf/source_context.pb.h" + +#include <algorithm> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/once.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/wire_format_lite_inl.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/reflection_ops.h> +#include <google/protobuf/wire_format.h> +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { + +namespace { + +const ::google::protobuf::Descriptor* SourceContext_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + SourceContext_reflection_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_google_2fprotobuf_2fsource_5fcontext_2eproto() { + protobuf_AddDesc_google_2fprotobuf_2fsource_5fcontext_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "google/protobuf/source_context.proto"); + GOOGLE_CHECK(file != NULL); + SourceContext_descriptor_ = file->message_type(0); + static const int SourceContext_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceContext, file_name_), + }; + SourceContext_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + SourceContext_descriptor_, + SourceContext::default_instance_, + SourceContext_offsets_, + -1, + -1, + -1, + sizeof(SourceContext), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceContext, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceContext, _is_default_instance_)); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_google_2fprotobuf_2fsource_5fcontext_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + SourceContext_descriptor_, &SourceContext::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_google_2fprotobuf_2fsource_5fcontext_2eproto() { + delete SourceContext::default_instance_; + delete SourceContext_reflection_; +} + +void protobuf_AddDesc_google_2fprotobuf_2fsource_5fcontext_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n$google/protobuf/source_context.proto\022\017" + "google.protobuf\"\"\n\rSourceContext\022\021\n\tfile" + "_name\030\001 \001(\tB1\n\023com.google.protobufB\022Sour" + "ceContextProtoP\001\242\002\003GPBb\006proto3", 150); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "google/protobuf/source_context.proto", &protobuf_RegisterTypes); + SourceContext::default_instance_ = new SourceContext(); + SourceContext::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_google_2fprotobuf_2fsource_5fcontext_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_google_2fprotobuf_2fsource_5fcontext_2eproto { + StaticDescriptorInitializer_google_2fprotobuf_2fsource_5fcontext_2eproto() { + protobuf_AddDesc_google_2fprotobuf_2fsource_5fcontext_2eproto(); + } +} static_descriptor_initializer_google_2fprotobuf_2fsource_5fcontext_2eproto_; + +namespace { + +static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD; +static void MergeFromFail(int line) { + GOOGLE_CHECK(false) << __FILE__ << ":" << line; +} + +} // namespace + + +// =================================================================== + +#ifndef _MSC_VER +const int SourceContext::kFileNameFieldNumber; +#endif // !_MSC_VER + +SourceContext::SourceContext() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:google.protobuf.SourceContext) +} + +void SourceContext::InitAsDefaultInstance() { + _is_default_instance_ = true; +} + +SourceContext::SourceContext(const SourceContext& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:google.protobuf.SourceContext) +} + +void SourceContext::SharedCtor() { + _is_default_instance_ = false; + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + file_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + +SourceContext::~SourceContext() { + // @@protoc_insertion_point(destructor:google.protobuf.SourceContext) + SharedDtor(); +} + +void SourceContext::SharedDtor() { + file_name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (this != default_instance_) { + } +} + +void SourceContext::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* SourceContext::descriptor() { + protobuf_AssignDescriptorsOnce(); + return SourceContext_descriptor_; +} + +const SourceContext& SourceContext::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fsource_5fcontext_2eproto(); + return *default_instance_; +} + +SourceContext* SourceContext::default_instance_ = NULL; + +SourceContext* SourceContext::New(::google::protobuf::Arena* arena) const { + SourceContext* n = new SourceContext; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void SourceContext::Clear() { + file_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + +bool SourceContext::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:google.protobuf.SourceContext) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string file_name = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_file_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->file_name().data(), this->file_name().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "google.protobuf.SourceContext.file_name"); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:google.protobuf.SourceContext) + return true; +failure: + // @@protoc_insertion_point(parse_failure:google.protobuf.SourceContext) + return false; +#undef DO_ +} + +void SourceContext::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:google.protobuf.SourceContext) + // optional string file_name = 1; + if (this->file_name().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->file_name().data(), this->file_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.SourceContext.file_name"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->file_name(), output); + } + + // @@protoc_insertion_point(serialize_end:google.protobuf.SourceContext) +} + +::google::protobuf::uint8* SourceContext::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.SourceContext) + // optional string file_name = 1; + if (this->file_name().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->file_name().data(), this->file_name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.SourceContext.file_name"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->file_name(), target); + } + + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.SourceContext) + return target; +} + +int SourceContext::ByteSize() const { + int total_size = 0; + + // optional string file_name = 1; + if (this->file_name().size() > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->file_name()); + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void SourceContext::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const SourceContext* source = + ::google::protobuf::internal::DynamicCastToGenerated<const SourceContext>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void SourceContext::MergeFrom(const SourceContext& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from.file_name().size() > 0) { + + file_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.file_name_); + } +} + +void SourceContext::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void SourceContext::CopyFrom(const SourceContext& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool SourceContext::IsInitialized() const { + + return true; +} + +void SourceContext::Swap(SourceContext* other) { + if (other == this) return; + InternalSwap(other); +} +void SourceContext::InternalSwap(SourceContext* other) { + file_name_.Swap(&other->file_name_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata SourceContext::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = SourceContext_descriptor_; + metadata.reflection = SourceContext_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// SourceContext + +// optional string file_name = 1; +void SourceContext::clear_file_name() { + file_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + const ::std::string& SourceContext::file_name() const { + // @@protoc_insertion_point(field_get:google.protobuf.SourceContext.file_name) + return file_name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void SourceContext::set_file_name(const ::std::string& value) { + + file_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.SourceContext.file_name) +} + void SourceContext::set_file_name(const char* value) { + + file_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.SourceContext.file_name) +} + void SourceContext::set_file_name(const char* value, size_t size) { + + file_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.SourceContext.file_name) +} + ::std::string* SourceContext::mutable_file_name() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.SourceContext.file_name) + return file_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* SourceContext::release_file_name() { + + return file_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void SourceContext::set_allocated_file_name(::std::string* file_name) { + if (file_name != NULL) { + + } else { + + } + file_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), file_name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.SourceContext.file_name) +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// @@protoc_insertion_point(namespace_scope) + +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) diff --git a/src/google/protobuf/source_context.pb.h b/src/google/protobuf/source_context.pb.h new file mode 100644 index 00000000..02e11460 --- /dev/null +++ b/src/google/protobuf/source_context.pb.h @@ -0,0 +1,185 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/source_context.proto + +#ifndef PROTOBUF_google_2fprotobuf_2fsource_5fcontext_2eproto__INCLUDED +#define PROTOBUF_google_2fprotobuf_2fsource_5fcontext_2eproto__INCLUDED + +#include <string> + +#include <google/protobuf/stubs/common.h> + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#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 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include <google/protobuf/arena.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/metadata.h> +#include <google/protobuf/message.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/unknown_field_set.h> +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { + +// Internal implementation detail -- do not call these. +void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fsource_5fcontext_2eproto(); +void protobuf_AssignDesc_google_2fprotobuf_2fsource_5fcontext_2eproto(); +void protobuf_ShutdownFile_google_2fprotobuf_2fsource_5fcontext_2eproto(); + +class SourceContext; + +// =================================================================== + +class LIBPROTOBUF_EXPORT SourceContext : public ::google::protobuf::Message { + public: + SourceContext(); + virtual ~SourceContext(); + + SourceContext(const SourceContext& from); + + inline SourceContext& operator=(const SourceContext& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const SourceContext& default_instance(); + + void Swap(SourceContext* other); + + // implements Message ---------------------------------------------- + + inline SourceContext* New() const { return New(NULL); } + + SourceContext* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const SourceContext& from); + void MergeFrom(const SourceContext& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(SourceContext* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string file_name = 1; + void clear_file_name(); + static const int kFileNameFieldNumber = 1; + const ::std::string& file_name() const; + void set_file_name(const ::std::string& value); + void set_file_name(const char* value); + void set_file_name(const char* value, size_t size); + ::std::string* mutable_file_name(); + ::std::string* release_file_name(); + void set_allocated_file_name(::std::string* file_name); + + // @@protoc_insertion_point(class_scope:google.protobuf.SourceContext) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr file_name_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fsource_5fcontext_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fsource_5fcontext_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fsource_5fcontext_2eproto(); + + void InitAsDefaultInstance(); + static SourceContext* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// SourceContext + +// optional string file_name = 1; +inline void SourceContext::clear_file_name() { + file_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& SourceContext::file_name() const { + // @@protoc_insertion_point(field_get:google.protobuf.SourceContext.file_name) + return file_name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void SourceContext::set_file_name(const ::std::string& value) { + + file_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.SourceContext.file_name) +} +inline void SourceContext::set_file_name(const char* value) { + + file_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.SourceContext.file_name) +} +inline void SourceContext::set_file_name(const char* value, size_t size) { + + file_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.SourceContext.file_name) +} +inline ::std::string* SourceContext::mutable_file_name() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.SourceContext.file_name) + return file_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* SourceContext::release_file_name() { + + return file_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void SourceContext::set_allocated_file_name(::std::string* file_name) { + if (file_name != NULL) { + + } else { + + } + file_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), file_name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.SourceContext.file_name) +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS + +// @@protoc_insertion_point(namespace_scope) + +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_google_2fprotobuf_2fsource_5fcontext_2eproto__INCLUDED diff --git a/src/google/protobuf/source_context.proto b/src/google/protobuf/source_context.proto index a3874d6a..2c8a17a8 100644 --- a/src/google/protobuf/source_context.proto +++ b/src/google/protobuf/source_context.proto @@ -34,6 +34,7 @@ package google.protobuf; option java_multiple_files = true; option java_outer_classname = "SourceContextProto"; option java_package = "com.google.protobuf"; +option objc_class_prefix = "GPB"; // `SourceContext` represents information about the source of a diff --git a/src/google/protobuf/struct.pb.cc b/src/google/protobuf/struct.pb.cc new file mode 100644 index 00000000..30113cdb --- /dev/null +++ b/src/google/protobuf/struct.pb.cc @@ -0,0 +1,1455 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/struct.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "google/protobuf/struct.pb.h" + +#include <algorithm> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/once.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/wire_format_lite_inl.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/reflection_ops.h> +#include <google/protobuf/wire_format.h> +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { + +namespace { + +const ::google::protobuf::Descriptor* Struct_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Struct_reflection_ = NULL; +const ::google::protobuf::Descriptor* Struct_FieldsEntry_descriptor_ = NULL; +const ::google::protobuf::Descriptor* Value_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Value_reflection_ = NULL; +struct ValueOneofInstance { + int null_value_; + double number_value_; + ::google::protobuf::internal::ArenaStringPtr string_value_; + bool bool_value_; + const ::google::protobuf::Struct* struct_value_; + const ::google::protobuf::ListValue* list_value_; +}* Value_default_oneof_instance_ = NULL; +const ::google::protobuf::Descriptor* ListValue_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + ListValue_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* NullValue_descriptor_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_google_2fprotobuf_2fstruct_2eproto() { + protobuf_AddDesc_google_2fprotobuf_2fstruct_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "google/protobuf/struct.proto"); + GOOGLE_CHECK(file != NULL); + Struct_descriptor_ = file->message_type(0); + static const int Struct_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Struct, fields_), + }; + Struct_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + Struct_descriptor_, + Struct::default_instance_, + Struct_offsets_, + -1, + -1, + -1, + sizeof(Struct), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Struct, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Struct, _is_default_instance_)); + Struct_FieldsEntry_descriptor_ = Struct_descriptor_->nested_type(0); + Value_descriptor_ = file->message_type(1); + static const int Value_offsets_[7] = { + PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(Value_default_oneof_instance_, null_value_), + PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(Value_default_oneof_instance_, number_value_), + PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(Value_default_oneof_instance_, string_value_), + PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(Value_default_oneof_instance_, bool_value_), + PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(Value_default_oneof_instance_, struct_value_), + PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(Value_default_oneof_instance_, list_value_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Value, kind_), + }; + Value_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + Value_descriptor_, + Value::default_instance_, + Value_offsets_, + -1, + -1, + -1, + Value_default_oneof_instance_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Value, _oneof_case_[0]), + sizeof(Value), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Value, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Value, _is_default_instance_)); + ListValue_descriptor_ = file->message_type(2); + static const int ListValue_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ListValue, values_), + }; + ListValue_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + ListValue_descriptor_, + ListValue::default_instance_, + ListValue_offsets_, + -1, + -1, + -1, + sizeof(ListValue), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ListValue, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ListValue, _is_default_instance_)); + NullValue_descriptor_ = file->enum_type(0); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_google_2fprotobuf_2fstruct_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Struct_descriptor_, &Struct::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Struct_FieldsEntry_descriptor_, + ::google::protobuf::internal::MapEntry< + ::std::string, + ::google::protobuf::Value, + ::google::protobuf::internal::WireFormatLite::TYPE_STRING, + ::google::protobuf::internal::WireFormatLite::TYPE_MESSAGE, + 0>::CreateDefaultInstance( + Struct_FieldsEntry_descriptor_)); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Value_descriptor_, &Value::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + ListValue_descriptor_, &ListValue::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_google_2fprotobuf_2fstruct_2eproto() { + delete Struct::default_instance_; + delete Struct_reflection_; + delete Value::default_instance_; + delete Value_default_oneof_instance_; + delete Value_reflection_; + delete ListValue::default_instance_; + delete ListValue_reflection_; +} + +void protobuf_AddDesc_google_2fprotobuf_2fstruct_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\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\000BF\n\023com.google.prot" + "obufB\013StructProtoP\001\240\001\001\242\002\003GPB\252\002\026Google.Pr" + "otocolBuffersb\006proto3", 581); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "google/protobuf/struct.proto", &protobuf_RegisterTypes); + Struct::default_instance_ = new Struct(); + Value::default_instance_ = new Value(); + Value_default_oneof_instance_ = new ValueOneofInstance(); + ListValue::default_instance_ = new ListValue(); + Struct::default_instance_->InitAsDefaultInstance(); + Value::default_instance_->InitAsDefaultInstance(); + ListValue::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_google_2fprotobuf_2fstruct_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_google_2fprotobuf_2fstruct_2eproto { + StaticDescriptorInitializer_google_2fprotobuf_2fstruct_2eproto() { + protobuf_AddDesc_google_2fprotobuf_2fstruct_2eproto(); + } +} static_descriptor_initializer_google_2fprotobuf_2fstruct_2eproto_; +const ::google::protobuf::EnumDescriptor* NullValue_descriptor() { + protobuf_AssignDescriptorsOnce(); + return NullValue_descriptor_; +} +bool NullValue_IsValid(int value) { + switch(value) { + case 0: + return true; + default: + return false; + } +} + + +namespace { + +static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD; +static void MergeFromFail(int line) { + GOOGLE_CHECK(false) << __FILE__ << ":" << line; +} + +} // namespace + + +// =================================================================== + +#ifndef _MSC_VER +const int Struct::kFieldsFieldNumber; +#endif // !_MSC_VER + +Struct::Struct() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:google.protobuf.Struct) +} + +void Struct::InitAsDefaultInstance() { + _is_default_instance_ = true; +} + +Struct::Struct(const Struct& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:google.protobuf.Struct) +} + +void Struct::SharedCtor() { + _is_default_instance_ = false; + _cached_size_ = 0; + fields_.SetAssignDescriptorCallback( + protobuf_AssignDescriptorsOnce); + fields_.SetEntryDescriptor( + &::google::protobuf::Struct_FieldsEntry_descriptor_); +} + +Struct::~Struct() { + // @@protoc_insertion_point(destructor:google.protobuf.Struct) + SharedDtor(); +} + +void Struct::SharedDtor() { + if (this != default_instance_) { + } +} + +void Struct::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Struct::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Struct_descriptor_; +} + +const Struct& Struct::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fstruct_2eproto(); + return *default_instance_; +} + +Struct* Struct::default_instance_ = NULL; + +Struct* Struct::New(::google::protobuf::Arena* arena) const { + Struct* n = new Struct; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void Struct::Clear() { + fields_.Clear(); +} + +bool Struct::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:google.protobuf.Struct) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // map<string, .google.protobuf.Value> fields = 1; + case 1: { + if (tag == 10) { + DO_(input->IncrementRecursionDepth()); + parse_loop_fields: + ::google::protobuf::scoped_ptr<Struct_FieldsEntry> entry(fields_.NewEntry()); + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, entry.get())); + (*mutable_fields())[entry->key()].Swap(entry->mutable_value()); + } else { + goto handle_unusual; + } + if (input->ExpectTag(10)) goto parse_loop_fields; + input->UnsafeDecrementRecursionDepth(); + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:google.protobuf.Struct) + return true; +failure: + // @@protoc_insertion_point(parse_failure:google.protobuf.Struct) + return false; +#undef DO_ +} + +void Struct::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:google.protobuf.Struct) + // map<string, .google.protobuf.Value> fields = 1; + { + ::google::protobuf::scoped_ptr<Struct_FieldsEntry> entry; + for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator + it = this->fields().begin(); + it != this->fields().end(); ++it) { + entry.reset(fields_.NewEntryWrapper(it->first, it->second)); + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, *entry, output); + } + } + + // @@protoc_insertion_point(serialize_end:google.protobuf.Struct) +} + +::google::protobuf::uint8* Struct::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Struct) + // map<string, .google.protobuf.Value> fields = 1; + { + ::google::protobuf::scoped_ptr<Struct_FieldsEntry> entry; + for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator + it = this->fields().begin(); + it != this->fields().end(); ++it) { + entry.reset(fields_.NewEntryWrapper(it->first, it->second)); + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, *entry, target); + } + } + + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Struct) + return target; +} + +int Struct::ByteSize() const { + int total_size = 0; + + // map<string, .google.protobuf.Value> fields = 1; + total_size += 1 * this->fields_size(); + { + ::google::protobuf::scoped_ptr<Struct_FieldsEntry> entry; + for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator + it = this->fields().begin(); + it != this->fields().end(); ++it) { + entry.reset(fields_.NewEntryWrapper(it->first, it->second)); + total_size += ::google::protobuf::internal::WireFormatLite:: + MessageSizeNoVirtual(*entry); + } + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Struct::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const Struct* source = + ::google::protobuf::internal::DynamicCastToGenerated<const Struct>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Struct::MergeFrom(const Struct& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + fields_.MergeFrom(from.fields_); +} + +void Struct::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Struct::CopyFrom(const Struct& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Struct::IsInitialized() const { + + return true; +} + +void Struct::Swap(Struct* other) { + if (other == this) return; + InternalSwap(other); +} +void Struct::InternalSwap(Struct* other) { + fields_.Swap(&other->fields_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata Struct::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Struct_descriptor_; + metadata.reflection = Struct_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// Struct + +// map<string, .google.protobuf.Value> fields = 1; +int Struct::fields_size() const { + return fields_.size(); +} +void Struct::clear_fields() { + fields_.Clear(); +} + const ::google::protobuf::Map< ::std::string, ::google::protobuf::Value >& +Struct::fields() const { + // @@protoc_insertion_point(field_map:google.protobuf.Struct.fields) + return fields_.GetMap(); +} + ::google::protobuf::Map< ::std::string, ::google::protobuf::Value >* +Struct::mutable_fields() { + // @@protoc_insertion_point(field_mutable_map:google.protobuf.Struct.fields) + return fields_.MutableMap(); +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// =================================================================== + +#ifndef _MSC_VER +const int Value::kNullValueFieldNumber; +const int Value::kNumberValueFieldNumber; +const int Value::kStringValueFieldNumber; +const int Value::kBoolValueFieldNumber; +const int Value::kStructValueFieldNumber; +const int Value::kListValueFieldNumber; +#endif // !_MSC_VER + +Value::Value() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:google.protobuf.Value) +} + +void Value::InitAsDefaultInstance() { + _is_default_instance_ = true; + Value_default_oneof_instance_->null_value_ = 0; + Value_default_oneof_instance_->number_value_ = 0; + Value_default_oneof_instance_->string_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + Value_default_oneof_instance_->bool_value_ = false; + Value_default_oneof_instance_->struct_value_ = const_cast< ::google::protobuf::Struct*>(&::google::protobuf::Struct::default_instance()); + Value_default_oneof_instance_->list_value_ = const_cast< ::google::protobuf::ListValue*>(&::google::protobuf::ListValue::default_instance()); +} + +Value::Value(const Value& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:google.protobuf.Value) +} + +void Value::SharedCtor() { + _is_default_instance_ = false; + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + clear_has_kind(); +} + +Value::~Value() { + // @@protoc_insertion_point(destructor:google.protobuf.Value) + SharedDtor(); +} + +void Value::SharedDtor() { + if (has_kind()) { + clear_kind(); + } + if (this != default_instance_) { + } +} + +void Value::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Value::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Value_descriptor_; +} + +const Value& Value::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fstruct_2eproto(); + return *default_instance_; +} + +Value* Value::default_instance_ = NULL; + +Value* Value::New(::google::protobuf::Arena* arena) const { + Value* n = new Value; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void Value::clear_kind() { + switch(kind_case()) { + case kNullValue: { + // No need to clear + break; + } + case kNumberValue: { + // No need to clear + break; + } + case kStringValue: { + kind_.string_value_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + break; + } + case kBoolValue: { + // No need to clear + break; + } + case kStructValue: { + delete kind_.struct_value_; + break; + } + case kListValue: { + delete kind_.list_value_; + break; + } + case KIND_NOT_SET: { + break; + } + } + _oneof_case_[0] = KIND_NOT_SET; +} + + +void Value::Clear() { + clear_kind(); +} + +bool Value::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:google.protobuf.Value) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional .google.protobuf.NullValue null_value = 1; + case 1: { + if (tag == 8) { + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + set_null_value(static_cast< ::google::protobuf::NullValue >(value)); + } else { + goto handle_unusual; + } + if (input->ExpectTag(17)) goto parse_number_value; + break; + } + + // optional double number_value = 2; + case 2: { + if (tag == 17) { + parse_number_value: + clear_kind(); + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>( + input, &kind_.number_value_))); + set_has_number_value(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(26)) goto parse_string_value; + break; + } + + // optional string string_value = 3; + case 3: { + if (tag == 26) { + parse_string_value: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_string_value())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->string_value().data(), this->string_value().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "google.protobuf.Value.string_value"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(32)) goto parse_bool_value; + break; + } + + // optional bool bool_value = 4; + case 4: { + if (tag == 32) { + parse_bool_value: + clear_kind(); + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &kind_.bool_value_))); + set_has_bool_value(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(42)) goto parse_struct_value; + break; + } + + // optional .google.protobuf.Struct struct_value = 5; + case 5: { + if (tag == 42) { + parse_struct_value: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_struct_value())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(50)) goto parse_list_value; + break; + } + + // optional .google.protobuf.ListValue list_value = 6; + case 6: { + if (tag == 50) { + parse_list_value: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_list_value())); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:google.protobuf.Value) + return true; +failure: + // @@protoc_insertion_point(parse_failure:google.protobuf.Value) + return false; +#undef DO_ +} + +void Value::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:google.protobuf.Value) + // optional .google.protobuf.NullValue null_value = 1; + if (has_null_value()) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 1, this->null_value(), output); + } + + // optional double number_value = 2; + if (has_number_value()) { + ::google::protobuf::internal::WireFormatLite::WriteDouble(2, this->number_value(), output); + } + + // optional string string_value = 3; + if (has_string_value()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->string_value().data(), this->string_value().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.Value.string_value"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 3, this->string_value(), output); + } + + // optional bool bool_value = 4; + if (has_bool_value()) { + ::google::protobuf::internal::WireFormatLite::WriteBool(4, this->bool_value(), output); + } + + // optional .google.protobuf.Struct struct_value = 5; + if (has_struct_value()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 5, *kind_.struct_value_, output); + } + + // optional .google.protobuf.ListValue list_value = 6; + if (has_list_value()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 6, *kind_.list_value_, output); + } + + // @@protoc_insertion_point(serialize_end:google.protobuf.Value) +} + +::google::protobuf::uint8* Value::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Value) + // optional .google.protobuf.NullValue null_value = 1; + if (has_null_value()) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 1, this->null_value(), target); + } + + // optional double number_value = 2; + if (has_number_value()) { + target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(2, this->number_value(), target); + } + + // optional string string_value = 3; + if (has_string_value()) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->string_value().data(), this->string_value().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.Value.string_value"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 3, this->string_value(), target); + } + + // optional bool bool_value = 4; + if (has_bool_value()) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(4, this->bool_value(), target); + } + + // optional .google.protobuf.Struct struct_value = 5; + if (has_struct_value()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 5, *kind_.struct_value_, target); + } + + // optional .google.protobuf.ListValue list_value = 6; + if (has_list_value()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 6, *kind_.list_value_, target); + } + + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Value) + return target; +} + +int Value::ByteSize() const { + int total_size = 0; + + switch (kind_case()) { + // optional .google.protobuf.NullValue null_value = 1; + case kNullValue: { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->null_value()); + break; + } + // optional double number_value = 2; + case kNumberValue: { + total_size += 1 + 8; + break; + } + // optional string string_value = 3; + case kStringValue: { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->string_value()); + break; + } + // optional bool bool_value = 4; + case kBoolValue: { + total_size += 1 + 1; + break; + } + // optional .google.protobuf.Struct struct_value = 5; + case kStructValue: { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + *kind_.struct_value_); + break; + } + // optional .google.protobuf.ListValue list_value = 6; + case kListValue: { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + *kind_.list_value_); + break; + } + case KIND_NOT_SET: { + break; + } + } + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Value::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const Value* source = + ::google::protobuf::internal::DynamicCastToGenerated<const Value>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Value::MergeFrom(const Value& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + switch (from.kind_case()) { + case kNullValue: { + set_null_value(from.null_value()); + break; + } + case kNumberValue: { + set_number_value(from.number_value()); + break; + } + case kStringValue: { + set_string_value(from.string_value()); + break; + } + case kBoolValue: { + set_bool_value(from.bool_value()); + break; + } + case kStructValue: { + mutable_struct_value()->::google::protobuf::Struct::MergeFrom(from.struct_value()); + break; + } + case kListValue: { + mutable_list_value()->::google::protobuf::ListValue::MergeFrom(from.list_value()); + break; + } + case KIND_NOT_SET: { + break; + } + } +} + +void Value::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Value::CopyFrom(const Value& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Value::IsInitialized() const { + + return true; +} + +void Value::Swap(Value* other) { + if (other == this) return; + InternalSwap(other); +} +void Value::InternalSwap(Value* other) { + std::swap(kind_, other->kind_); + std::swap(_oneof_case_[0], other->_oneof_case_[0]); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata Value::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Value_descriptor_; + metadata.reflection = Value_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// Value + +// optional .google.protobuf.NullValue null_value = 1; +bool Value::has_null_value() const { + return kind_case() == kNullValue; +} +void Value::set_has_null_value() { + _oneof_case_[0] = kNullValue; +} +void Value::clear_null_value() { + if (has_null_value()) { + kind_.null_value_ = 0; + clear_has_kind(); + } +} + ::google::protobuf::NullValue Value::null_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Value.null_value) + if (has_null_value()) { + return static_cast< ::google::protobuf::NullValue >(kind_.null_value_); + } + return static_cast< ::google::protobuf::NullValue >(0); +} + void Value::set_null_value(::google::protobuf::NullValue value) { + if (!has_null_value()) { + clear_kind(); + set_has_null_value(); + } + kind_.null_value_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Value.null_value) +} + +// optional double number_value = 2; +bool Value::has_number_value() const { + return kind_case() == kNumberValue; +} +void Value::set_has_number_value() { + _oneof_case_[0] = kNumberValue; +} +void Value::clear_number_value() { + if (has_number_value()) { + kind_.number_value_ = 0; + clear_has_kind(); + } +} + double Value::number_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Value.number_value) + if (has_number_value()) { + return kind_.number_value_; + } + return 0; +} + void Value::set_number_value(double value) { + if (!has_number_value()) { + clear_kind(); + set_has_number_value(); + } + kind_.number_value_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Value.number_value) +} + +// optional string string_value = 3; +bool Value::has_string_value() const { + return kind_case() == kStringValue; +} +void Value::set_has_string_value() { + _oneof_case_[0] = kStringValue; +} +void Value::clear_string_value() { + if (has_string_value()) { + kind_.string_value_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_kind(); + } +} + const ::std::string& Value::string_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Value.string_value) + if (has_string_value()) { + return kind_.string_value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + return *&::google::protobuf::internal::GetEmptyStringAlreadyInited(); +} + void Value::set_string_value(const ::std::string& value) { + // @@protoc_insertion_point(field_set:google.protobuf.Value.string_value) + if (!has_string_value()) { + clear_kind(); + set_has_string_value(); + kind_.string_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + kind_.string_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Value.string_value) +} + void Value::set_string_value(const char* value) { + if (!has_string_value()) { + clear_kind(); + set_has_string_value(); + kind_.string_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + kind_.string_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Value.string_value) +} + void Value::set_string_value(const char* value, size_t size) { + if (!has_string_value()) { + clear_kind(); + set_has_string_value(); + kind_.string_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + kind_.string_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string( + reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Value.string_value) +} + ::std::string* Value::mutable_string_value() { + if (!has_string_value()) { + clear_kind(); + set_has_string_value(); + kind_.string_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_mutable:google.protobuf.Value.string_value) + return kind_.string_value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* Value::release_string_value() { + if (has_string_value()) { + clear_has_kind(); + return kind_.string_value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } else { + return NULL; + } +} + void Value::set_allocated_string_value(::std::string* string_value) { + if (!has_string_value()) { + kind_.string_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + clear_kind(); + if (string_value != NULL) { + set_has_string_value(); + kind_.string_value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + string_value); + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Value.string_value) +} + +// optional bool bool_value = 4; +bool Value::has_bool_value() const { + return kind_case() == kBoolValue; +} +void Value::set_has_bool_value() { + _oneof_case_[0] = kBoolValue; +} +void Value::clear_bool_value() { + if (has_bool_value()) { + kind_.bool_value_ = false; + clear_has_kind(); + } +} + bool Value::bool_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Value.bool_value) + if (has_bool_value()) { + return kind_.bool_value_; + } + return false; +} + void Value::set_bool_value(bool value) { + if (!has_bool_value()) { + clear_kind(); + set_has_bool_value(); + } + kind_.bool_value_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Value.bool_value) +} + +// optional .google.protobuf.Struct struct_value = 5; +bool Value::has_struct_value() const { + return kind_case() == kStructValue; +} +void Value::set_has_struct_value() { + _oneof_case_[0] = kStructValue; +} +void Value::clear_struct_value() { + if (has_struct_value()) { + delete kind_.struct_value_; + clear_has_kind(); + } +} + const ::google::protobuf::Struct& Value::struct_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Value.struct_value) + return has_struct_value() ? *kind_.struct_value_ + : ::google::protobuf::Struct::default_instance(); +} + ::google::protobuf::Struct* Value::mutable_struct_value() { + if (!has_struct_value()) { + clear_kind(); + set_has_struct_value(); + kind_.struct_value_ = new ::google::protobuf::Struct; + } + // @@protoc_insertion_point(field_mutable:google.protobuf.Value.struct_value) + return kind_.struct_value_; +} + ::google::protobuf::Struct* Value::release_struct_value() { + if (has_struct_value()) { + clear_has_kind(); + ::google::protobuf::Struct* temp = kind_.struct_value_; + kind_.struct_value_ = NULL; + return temp; + } else { + return NULL; + } +} + void Value::set_allocated_struct_value(::google::protobuf::Struct* struct_value) { + clear_kind(); + if (struct_value) { + set_has_struct_value(); + kind_.struct_value_ = struct_value; + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Value.struct_value) +} + +// optional .google.protobuf.ListValue list_value = 6; +bool Value::has_list_value() const { + return kind_case() == kListValue; +} +void Value::set_has_list_value() { + _oneof_case_[0] = kListValue; +} +void Value::clear_list_value() { + if (has_list_value()) { + delete kind_.list_value_; + clear_has_kind(); + } +} + const ::google::protobuf::ListValue& Value::list_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Value.list_value) + return has_list_value() ? *kind_.list_value_ + : ::google::protobuf::ListValue::default_instance(); +} + ::google::protobuf::ListValue* Value::mutable_list_value() { + if (!has_list_value()) { + clear_kind(); + set_has_list_value(); + kind_.list_value_ = new ::google::protobuf::ListValue; + } + // @@protoc_insertion_point(field_mutable:google.protobuf.Value.list_value) + return kind_.list_value_; +} + ::google::protobuf::ListValue* Value::release_list_value() { + if (has_list_value()) { + clear_has_kind(); + ::google::protobuf::ListValue* temp = kind_.list_value_; + kind_.list_value_ = NULL; + return temp; + } else { + return NULL; + } +} + void Value::set_allocated_list_value(::google::protobuf::ListValue* list_value) { + clear_kind(); + if (list_value) { + set_has_list_value(); + kind_.list_value_ = list_value; + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Value.list_value) +} + +bool Value::has_kind() const { + return kind_case() != KIND_NOT_SET; +} +void Value::clear_has_kind() { + _oneof_case_[0] = KIND_NOT_SET; +} +Value::KindCase Value::kind_case() const { + return Value::KindCase(_oneof_case_[0]); +} +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// =================================================================== + +#ifndef _MSC_VER +const int ListValue::kValuesFieldNumber; +#endif // !_MSC_VER + +ListValue::ListValue() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:google.protobuf.ListValue) +} + +void ListValue::InitAsDefaultInstance() { + _is_default_instance_ = true; +} + +ListValue::ListValue(const ListValue& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:google.protobuf.ListValue) +} + +void ListValue::SharedCtor() { + _is_default_instance_ = false; + _cached_size_ = 0; +} + +ListValue::~ListValue() { + // @@protoc_insertion_point(destructor:google.protobuf.ListValue) + SharedDtor(); +} + +void ListValue::SharedDtor() { + if (this != default_instance_) { + } +} + +void ListValue::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* ListValue::descriptor() { + protobuf_AssignDescriptorsOnce(); + return ListValue_descriptor_; +} + +const ListValue& ListValue::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fstruct_2eproto(); + return *default_instance_; +} + +ListValue* ListValue::default_instance_ = NULL; + +ListValue* ListValue::New(::google::protobuf::Arena* arena) const { + ListValue* n = new ListValue; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void ListValue::Clear() { + values_.Clear(); +} + +bool ListValue::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:google.protobuf.ListValue) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated .google.protobuf.Value values = 1; + case 1: { + if (tag == 10) { + DO_(input->IncrementRecursionDepth()); + parse_loop_values: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + input, add_values())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(10)) goto parse_loop_values; + input->UnsafeDecrementRecursionDepth(); + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:google.protobuf.ListValue) + return true; +failure: + // @@protoc_insertion_point(parse_failure:google.protobuf.ListValue) + return false; +#undef DO_ +} + +void ListValue::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:google.protobuf.ListValue) + // repeated .google.protobuf.Value values = 1; + for (unsigned int i = 0, n = this->values_size(); i < n; i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->values(i), output); + } + + // @@protoc_insertion_point(serialize_end:google.protobuf.ListValue) +} + +::google::protobuf::uint8* ListValue::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.ListValue) + // repeated .google.protobuf.Value values = 1; + for (unsigned int i = 0, n = this->values_size(); i < n; i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 1, this->values(i), target); + } + + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ListValue) + return target; +} + +int ListValue::ByteSize() const { + int total_size = 0; + + // repeated .google.protobuf.Value values = 1; + total_size += 1 * this->values_size(); + for (int i = 0; i < this->values_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->values(i)); + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void ListValue::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const ListValue* source = + ::google::protobuf::internal::DynamicCastToGenerated<const ListValue>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void ListValue::MergeFrom(const ListValue& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + values_.MergeFrom(from.values_); +} + +void ListValue::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void ListValue::CopyFrom(const ListValue& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool ListValue::IsInitialized() const { + + return true; +} + +void ListValue::Swap(ListValue* other) { + if (other == this) return; + InternalSwap(other); +} +void ListValue::InternalSwap(ListValue* other) { + values_.UnsafeArenaSwap(&other->values_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata ListValue::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = ListValue_descriptor_; + metadata.reflection = ListValue_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// ListValue + +// repeated .google.protobuf.Value values = 1; +int ListValue::values_size() const { + return values_.size(); +} +void ListValue::clear_values() { + values_.Clear(); +} + const ::google::protobuf::Value& ListValue::values(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.ListValue.values) + return values_.Get(index); +} + ::google::protobuf::Value* ListValue::mutable_values(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.ListValue.values) + return values_.Mutable(index); +} + ::google::protobuf::Value* ListValue::add_values() { + // @@protoc_insertion_point(field_add:google.protobuf.ListValue.values) + return values_.Add(); +} + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Value >& +ListValue::values() const { + // @@protoc_insertion_point(field_list:google.protobuf.ListValue.values) + return values_; +} + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Value >* +ListValue::mutable_values() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.ListValue.values) + return &values_; +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// @@protoc_insertion_point(namespace_scope) + +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) diff --git a/src/google/protobuf/struct.pb.h b/src/google/protobuf/struct.pb.h new file mode 100644 index 00000000..2889c8fe --- /dev/null +++ b/src/google/protobuf/struct.pb.h @@ -0,0 +1,764 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/struct.proto + +#ifndef PROTOBUF_google_2fprotobuf_2fstruct_2eproto__INCLUDED +#define PROTOBUF_google_2fprotobuf_2fstruct_2eproto__INCLUDED + +#include <string> + +#include <google/protobuf/stubs/common.h> + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#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 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include <google/protobuf/arena.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/metadata.h> +#include <google/protobuf/message.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/map.h> +#include <google/protobuf/map_field_inl.h> +#include <google/protobuf/generated_enum_reflection.h> +#include <google/protobuf/unknown_field_set.h> +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { + +// Internal implementation detail -- do not call these. +void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fstruct_2eproto(); +void protobuf_AssignDesc_google_2fprotobuf_2fstruct_2eproto(); +void protobuf_ShutdownFile_google_2fprotobuf_2fstruct_2eproto(); + +class Struct; +class Value; +class ListValue; + +enum NullValue { + NULL_VALUE = 0, + NullValue_INT_MIN_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32min, + NullValue_INT_MAX_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32max +}; +LIBPROTOBUF_EXPORT bool NullValue_IsValid(int value); +const NullValue NullValue_MIN = NULL_VALUE; +const NullValue NullValue_MAX = NULL_VALUE; +const int NullValue_ARRAYSIZE = NullValue_MAX + 1; + +LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* NullValue_descriptor(); +inline const ::std::string& NullValue_Name(NullValue value) { + return ::google::protobuf::internal::NameOfEnum( + NullValue_descriptor(), value); +} +inline bool NullValue_Parse( + const ::std::string& name, NullValue* value) { + return ::google::protobuf::internal::ParseNamedEnum<NullValue>( + NullValue_descriptor(), name, value); +} +// =================================================================== + +class LIBPROTOBUF_EXPORT Struct : public ::google::protobuf::Message { + public: + Struct(); + virtual ~Struct(); + + Struct(const Struct& from); + + inline Struct& operator=(const Struct& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Struct& default_instance(); + + void Swap(Struct* other); + + // implements Message ---------------------------------------------- + + inline Struct* New() const { return New(NULL); } + + Struct* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Struct& from); + void MergeFrom(const Struct& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Struct* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + + // accessors ------------------------------------------------------- + + // map<string, .google.protobuf.Value> fields = 1; + int fields_size() const; + void clear_fields(); + static const int kFieldsFieldNumber = 1; + const ::google::protobuf::Map< ::std::string, ::google::protobuf::Value >& + fields() const; + ::google::protobuf::Map< ::std::string, ::google::protobuf::Value >* + mutable_fields(); + + // @@protoc_insertion_point(class_scope:google.protobuf.Struct) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + typedef ::google::protobuf::internal::MapEntryLite< + ::std::string, ::google::protobuf::Value, + ::google::protobuf::internal::WireFormatLite::TYPE_STRING, + ::google::protobuf::internal::WireFormatLite::TYPE_MESSAGE, + 0 > + Struct_FieldsEntry; + ::google::protobuf::internal::MapField< + ::std::string, ::google::protobuf::Value, + ::google::protobuf::internal::WireFormatLite::TYPE_STRING, + ::google::protobuf::internal::WireFormatLite::TYPE_MESSAGE, + 0 > fields_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fstruct_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fstruct_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fstruct_2eproto(); + + void InitAsDefaultInstance(); + static Struct* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT Value : public ::google::protobuf::Message { + public: + Value(); + virtual ~Value(); + + Value(const Value& from); + + inline Value& operator=(const Value& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Value& default_instance(); + + enum KindCase { + kNullValue = 1, + kNumberValue = 2, + kStringValue = 3, + kBoolValue = 4, + kStructValue = 5, + kListValue = 6, + KIND_NOT_SET = 0, + }; + + void Swap(Value* other); + + // implements Message ---------------------------------------------- + + inline Value* New() const { return New(NULL); } + + Value* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Value& from); + void MergeFrom(const Value& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Value* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional .google.protobuf.NullValue null_value = 1; + private: + bool has_null_value() const; + public: + void clear_null_value(); + static const int kNullValueFieldNumber = 1; + ::google::protobuf::NullValue null_value() const; + void set_null_value(::google::protobuf::NullValue value); + + // optional double number_value = 2; + private: + bool has_number_value() const; + public: + void clear_number_value(); + static const int kNumberValueFieldNumber = 2; + double number_value() const; + void set_number_value(double value); + + // optional string string_value = 3; + private: + bool has_string_value() const; + public: + void clear_string_value(); + static const int kStringValueFieldNumber = 3; + const ::std::string& string_value() const; + void set_string_value(const ::std::string& value); + void set_string_value(const char* value); + void set_string_value(const char* value, size_t size); + ::std::string* mutable_string_value(); + ::std::string* release_string_value(); + void set_allocated_string_value(::std::string* string_value); + + // optional bool bool_value = 4; + private: + bool has_bool_value() const; + public: + void clear_bool_value(); + static const int kBoolValueFieldNumber = 4; + bool bool_value() const; + void set_bool_value(bool value); + + // optional .google.protobuf.Struct struct_value = 5; + bool has_struct_value() const; + void clear_struct_value(); + static const int kStructValueFieldNumber = 5; + const ::google::protobuf::Struct& struct_value() const; + ::google::protobuf::Struct* mutable_struct_value(); + ::google::protobuf::Struct* release_struct_value(); + void set_allocated_struct_value(::google::protobuf::Struct* struct_value); + + // optional .google.protobuf.ListValue list_value = 6; + bool has_list_value() const; + void clear_list_value(); + static const int kListValueFieldNumber = 6; + const ::google::protobuf::ListValue& list_value() const; + ::google::protobuf::ListValue* mutable_list_value(); + ::google::protobuf::ListValue* release_list_value(); + void set_allocated_list_value(::google::protobuf::ListValue* list_value); + + KindCase kind_case() const; + // @@protoc_insertion_point(class_scope:google.protobuf.Value) + private: + inline void set_has_null_value(); + inline void set_has_number_value(); + inline void set_has_string_value(); + inline void set_has_bool_value(); + inline void set_has_struct_value(); + inline void set_has_list_value(); + + inline bool has_kind() const; + void clear_kind(); + inline void clear_has_kind(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + union KindUnion { + KindUnion() {} + int null_value_; + double number_value_; + ::google::protobuf::internal::ArenaStringPtr string_value_; + bool bool_value_; + ::google::protobuf::Struct* struct_value_; + ::google::protobuf::ListValue* list_value_; + } kind_; + mutable int _cached_size_; + ::google::protobuf::uint32 _oneof_case_[1]; + + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fstruct_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fstruct_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fstruct_2eproto(); + + void InitAsDefaultInstance(); + static Value* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT ListValue : public ::google::protobuf::Message { + public: + ListValue(); + virtual ~ListValue(); + + ListValue(const ListValue& from); + + inline ListValue& operator=(const ListValue& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const ListValue& default_instance(); + + void Swap(ListValue* other); + + // implements Message ---------------------------------------------- + + inline ListValue* New() const { return New(NULL); } + + ListValue* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const ListValue& from); + void MergeFrom(const ListValue& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(ListValue* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated .google.protobuf.Value values = 1; + int values_size() const; + void clear_values(); + static const int kValuesFieldNumber = 1; + const ::google::protobuf::Value& values(int index) const; + ::google::protobuf::Value* mutable_values(int index); + ::google::protobuf::Value* add_values(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Value >& + values() const; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Value >* + mutable_values(); + + // @@protoc_insertion_point(class_scope:google.protobuf.ListValue) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Value > values_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fstruct_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fstruct_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fstruct_2eproto(); + + void InitAsDefaultInstance(); + static ListValue* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// Struct + +// map<string, .google.protobuf.Value> fields = 1; +inline int Struct::fields_size() const { + return fields_.size(); +} +inline void Struct::clear_fields() { + fields_.Clear(); +} +inline const ::google::protobuf::Map< ::std::string, ::google::protobuf::Value >& +Struct::fields() const { + // @@protoc_insertion_point(field_map:google.protobuf.Struct.fields) + return fields_.GetMap(); +} +inline ::google::protobuf::Map< ::std::string, ::google::protobuf::Value >* +Struct::mutable_fields() { + // @@protoc_insertion_point(field_mutable_map:google.protobuf.Struct.fields) + return fields_.MutableMap(); +} + +// ------------------------------------------------------------------- + +// Value + +// optional .google.protobuf.NullValue null_value = 1; +inline bool Value::has_null_value() const { + return kind_case() == kNullValue; +} +inline void Value::set_has_null_value() { + _oneof_case_[0] = kNullValue; +} +inline void Value::clear_null_value() { + if (has_null_value()) { + kind_.null_value_ = 0; + clear_has_kind(); + } +} +inline ::google::protobuf::NullValue Value::null_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Value.null_value) + if (has_null_value()) { + return static_cast< ::google::protobuf::NullValue >(kind_.null_value_); + } + return static_cast< ::google::protobuf::NullValue >(0); +} +inline void Value::set_null_value(::google::protobuf::NullValue value) { + if (!has_null_value()) { + clear_kind(); + set_has_null_value(); + } + kind_.null_value_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Value.null_value) +} + +// optional double number_value = 2; +inline bool Value::has_number_value() const { + return kind_case() == kNumberValue; +} +inline void Value::set_has_number_value() { + _oneof_case_[0] = kNumberValue; +} +inline void Value::clear_number_value() { + if (has_number_value()) { + kind_.number_value_ = 0; + clear_has_kind(); + } +} +inline double Value::number_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Value.number_value) + if (has_number_value()) { + return kind_.number_value_; + } + return 0; +} +inline void Value::set_number_value(double value) { + if (!has_number_value()) { + clear_kind(); + set_has_number_value(); + } + kind_.number_value_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Value.number_value) +} + +// optional string string_value = 3; +inline bool Value::has_string_value() const { + return kind_case() == kStringValue; +} +inline void Value::set_has_string_value() { + _oneof_case_[0] = kStringValue; +} +inline void Value::clear_string_value() { + if (has_string_value()) { + kind_.string_value_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_kind(); + } +} +inline const ::std::string& Value::string_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Value.string_value) + if (has_string_value()) { + return kind_.string_value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + return *&::google::protobuf::internal::GetEmptyStringAlreadyInited(); +} +inline void Value::set_string_value(const ::std::string& value) { + // @@protoc_insertion_point(field_set:google.protobuf.Value.string_value) + if (!has_string_value()) { + clear_kind(); + set_has_string_value(); + kind_.string_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + kind_.string_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Value.string_value) +} +inline void Value::set_string_value(const char* value) { + if (!has_string_value()) { + clear_kind(); + set_has_string_value(); + kind_.string_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + kind_.string_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Value.string_value) +} +inline void Value::set_string_value(const char* value, size_t size) { + if (!has_string_value()) { + clear_kind(); + set_has_string_value(); + kind_.string_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + kind_.string_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string( + reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Value.string_value) +} +inline ::std::string* Value::mutable_string_value() { + if (!has_string_value()) { + clear_kind(); + set_has_string_value(); + kind_.string_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_mutable:google.protobuf.Value.string_value) + return kind_.string_value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* Value::release_string_value() { + if (has_string_value()) { + clear_has_kind(); + return kind_.string_value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } else { + return NULL; + } +} +inline void Value::set_allocated_string_value(::std::string* string_value) { + if (!has_string_value()) { + kind_.string_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + clear_kind(); + if (string_value != NULL) { + set_has_string_value(); + kind_.string_value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + string_value); + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Value.string_value) +} + +// optional bool bool_value = 4; +inline bool Value::has_bool_value() const { + return kind_case() == kBoolValue; +} +inline void Value::set_has_bool_value() { + _oneof_case_[0] = kBoolValue; +} +inline void Value::clear_bool_value() { + if (has_bool_value()) { + kind_.bool_value_ = false; + clear_has_kind(); + } +} +inline bool Value::bool_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Value.bool_value) + if (has_bool_value()) { + return kind_.bool_value_; + } + return false; +} +inline void Value::set_bool_value(bool value) { + if (!has_bool_value()) { + clear_kind(); + set_has_bool_value(); + } + kind_.bool_value_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Value.bool_value) +} + +// optional .google.protobuf.Struct struct_value = 5; +inline bool Value::has_struct_value() const { + return kind_case() == kStructValue; +} +inline void Value::set_has_struct_value() { + _oneof_case_[0] = kStructValue; +} +inline void Value::clear_struct_value() { + if (has_struct_value()) { + delete kind_.struct_value_; + clear_has_kind(); + } +} +inline const ::google::protobuf::Struct& Value::struct_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Value.struct_value) + return has_struct_value() ? *kind_.struct_value_ + : ::google::protobuf::Struct::default_instance(); +} +inline ::google::protobuf::Struct* Value::mutable_struct_value() { + if (!has_struct_value()) { + clear_kind(); + set_has_struct_value(); + kind_.struct_value_ = new ::google::protobuf::Struct; + } + // @@protoc_insertion_point(field_mutable:google.protobuf.Value.struct_value) + return kind_.struct_value_; +} +inline ::google::protobuf::Struct* Value::release_struct_value() { + if (has_struct_value()) { + clear_has_kind(); + ::google::protobuf::Struct* temp = kind_.struct_value_; + kind_.struct_value_ = NULL; + return temp; + } else { + return NULL; + } +} +inline void Value::set_allocated_struct_value(::google::protobuf::Struct* struct_value) { + clear_kind(); + if (struct_value) { + set_has_struct_value(); + kind_.struct_value_ = struct_value; + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Value.struct_value) +} + +// optional .google.protobuf.ListValue list_value = 6; +inline bool Value::has_list_value() const { + return kind_case() == kListValue; +} +inline void Value::set_has_list_value() { + _oneof_case_[0] = kListValue; +} +inline void Value::clear_list_value() { + if (has_list_value()) { + delete kind_.list_value_; + clear_has_kind(); + } +} +inline const ::google::protobuf::ListValue& Value::list_value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Value.list_value) + return has_list_value() ? *kind_.list_value_ + : ::google::protobuf::ListValue::default_instance(); +} +inline ::google::protobuf::ListValue* Value::mutable_list_value() { + if (!has_list_value()) { + clear_kind(); + set_has_list_value(); + kind_.list_value_ = new ::google::protobuf::ListValue; + } + // @@protoc_insertion_point(field_mutable:google.protobuf.Value.list_value) + return kind_.list_value_; +} +inline ::google::protobuf::ListValue* Value::release_list_value() { + if (has_list_value()) { + clear_has_kind(); + ::google::protobuf::ListValue* temp = kind_.list_value_; + kind_.list_value_ = NULL; + return temp; + } else { + return NULL; + } +} +inline void Value::set_allocated_list_value(::google::protobuf::ListValue* list_value) { + clear_kind(); + if (list_value) { + set_has_list_value(); + kind_.list_value_ = list_value; + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Value.list_value) +} + +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::values_size() const { + return values_.size(); +} +inline void ListValue::clear_values() { + values_.Clear(); +} +inline const ::google::protobuf::Value& ListValue::values(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.ListValue.values) + return values_.Get(index); +} +inline ::google::protobuf::Value* ListValue::mutable_values(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.ListValue.values) + return values_.Mutable(index); +} +inline ::google::protobuf::Value* ListValue::add_values() { + // @@protoc_insertion_point(field_add:google.protobuf.ListValue.values) + return values_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Value >& +ListValue::values() const { + // @@protoc_insertion_point(field_list:google.protobuf.ListValue.values) + return values_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::Value >* +ListValue::mutable_values() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.ListValue.values) + return &values_; +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace protobuf +} // namespace google + +#ifndef SWIG +namespace google { +namespace protobuf { + +template <> struct is_proto_enum< ::google::protobuf::NullValue> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::NullValue>() { + return ::google::protobuf::NullValue_descriptor(); +} + +} // namespace protobuf +} // namespace google +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_google_2fprotobuf_2fstruct_2eproto__INCLUDED diff --git a/src/google/protobuf/struct.proto b/src/google/protobuf/struct.proto index 3a90ff37..cd102731 100644 --- a/src/google/protobuf/struct.proto +++ b/src/google/protobuf/struct.proto @@ -35,6 +35,8 @@ option java_generate_equals_and_hash = true; option java_multiple_files = true; option java_outer_classname = "StructProto"; option java_package = "com.google.protobuf"; +option csharp_namespace = "Google.ProtocolBuffers"; +option objc_class_prefix = "GPB"; // `Struct` represents a structured data value, consisting of fields diff --git a/src/google/protobuf/stubs/atomicops_internals_pnacl.h b/src/google/protobuf/stubs/atomicops_internals_pnacl.h index b10ac02c..3b314fd0 100644 --- a/src/google/protobuf/stubs/atomicops_internals_pnacl.h +++ b/src/google/protobuf/stubs/atomicops_internals_pnacl.h @@ -33,39 +33,197 @@ #ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_PNACL_H_ #define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_PNACL_H_ +#include <atomic> + namespace google { namespace protobuf { namespace internal { +// This implementation is transitional and maintains the original API for +// atomicops.h. This requires casting memory locations to the atomic types, and +// assumes that the API and the C++11 implementation are layout-compatible, +// which isn't true for all implementations or hardware platforms. The static +// assertion should detect this issue, were it to fire then this header +// shouldn't be used. +// +// TODO(jfb) If this header manages to stay committed then the API should be +// modified, and all call sites updated. +typedef volatile std::atomic<Atomic32>* AtomicLocation32; +static_assert(sizeof(*(AtomicLocation32) nullptr) == sizeof(Atomic32), + "incompatible 32-bit atomic layout"); + +inline void MemoryBarrier() { +#if defined(__GLIBCXX__) + // Work around libstdc++ bug 51038 where atomic_thread_fence was declared but + // not defined, leading to the linker complaining about undefined references. + __atomic_thread_fence(std::memory_order_seq_cst); +#else + std::atomic_thread_fence(std::memory_order_seq_cst); +#endif +} + inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, Atomic32 old_value, Atomic32 new_value) { - return __sync_val_compare_and_swap(ptr, old_value, new_value); + ((AtomicLocation32)ptr) + ->compare_exchange_strong(old_value, + new_value, + std::memory_order_relaxed, + std::memory_order_relaxed); + return old_value; } -inline void MemoryBarrier() { - __sync_synchronize(); +inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, + Atomic32 new_value) { + return ((AtomicLocation32)ptr) + ->exchange(new_value, std::memory_order_relaxed); +} + +inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + return increment + + ((AtomicLocation32)ptr) + ->fetch_add(increment, std::memory_order_relaxed); +} + +inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr, + Atomic32 increment) { + return increment + ((AtomicLocation32)ptr)->fetch_add(increment); } inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, Atomic32 old_value, Atomic32 new_value) { - Atomic32 ret = NoBarrier_CompareAndSwap(ptr, old_value, new_value); + ((AtomicLocation32)ptr) + ->compare_exchange_strong(old_value, + new_value, + std::memory_order_acquire, + std::memory_order_acquire); + return old_value; +} + +inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr, + Atomic32 old_value, + Atomic32 new_value) { + ((AtomicLocation32)ptr) + ->compare_exchange_strong(old_value, + new_value, + std::memory_order_release, + std::memory_order_relaxed); + return old_value; +} + +inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) { + ((AtomicLocation32)ptr)->store(value, std::memory_order_relaxed); +} + +inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { + ((AtomicLocation32)ptr)->store(value, std::memory_order_relaxed); MemoryBarrier(); - return ret; } inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) { - MemoryBarrier(); - *ptr = value; + ((AtomicLocation32)ptr)->store(value, std::memory_order_release); +} + +inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { + return ((AtomicLocation32)ptr)->load(std::memory_order_relaxed); } inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) { - Atomic32 value = *ptr; + return ((AtomicLocation32)ptr)->load(std::memory_order_acquire); +} + +inline Atomic32 Release_Load(volatile const Atomic32* ptr) { + MemoryBarrier(); + return ((AtomicLocation32)ptr)->load(std::memory_order_relaxed); +} + +#if defined(GOOGLE_PROTOBUF_ARCH_64_BIT) + +typedef volatile std::atomic<Atomic64>* AtomicLocation64; +static_assert(sizeof(*(AtomicLocation64) nullptr) == sizeof(Atomic64), + "incompatible 64-bit atomic layout"); + +inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + ((AtomicLocation64)ptr) + ->compare_exchange_strong(old_value, + new_value, + std::memory_order_relaxed, + std::memory_order_relaxed); + return old_value; +} + +inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, + Atomic64 new_value) { + return ((AtomicLocation64)ptr) + ->exchange(new_value, std::memory_order_relaxed); +} + +inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, + Atomic64 increment) { + return increment + + ((AtomicLocation64)ptr) + ->fetch_add(increment, std::memory_order_relaxed); +} + +inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, + Atomic64 increment) { + return increment + ((AtomicLocation64)ptr)->fetch_add(increment); +} + +inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + ((AtomicLocation64)ptr) + ->compare_exchange_strong(old_value, + new_value, + std::memory_order_acquire, + std::memory_order_acquire); + return old_value; +} + +inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr, + Atomic64 old_value, + Atomic64 new_value) { + ((AtomicLocation64)ptr) + ->compare_exchange_strong(old_value, + new_value, + std::memory_order_release, + std::memory_order_relaxed); + return old_value; +} + +inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) { + ((AtomicLocation64)ptr)->store(value, std::memory_order_relaxed); +} + +inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) { + ((AtomicLocation64)ptr)->store(value, std::memory_order_relaxed); MemoryBarrier(); - return value; } +inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) { + ((AtomicLocation64)ptr)->store(value, std::memory_order_release); +} + +inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) { + return ((AtomicLocation64)ptr)->load(std::memory_order_relaxed); +} + +inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) { + return ((AtomicLocation64)ptr)->load(std::memory_order_acquire); +} + +inline Atomic64 Release_Load(volatile const Atomic64* ptr) { + MemoryBarrier(); + return ((AtomicLocation64)ptr)->load(std::memory_order_relaxed); +} + +#endif // defined(GOOGLE_PROTOBUF_ARCH_64_BIT) + } // namespace internal } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h index c3f735a2..3acaeba1 100644 --- a/src/google/protobuf/stubs/common.h +++ b/src/google/protobuf/stubs/common.h @@ -62,6 +62,14 @@ #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 + #if defined(_WIN32) && defined(GetMessage) // Allow GetMessage to be used as a valid method name in protobuf classes. // windows.h defines GetMessage() as a macro. Let's re-define it as an inline @@ -157,7 +165,7 @@ std::string LIBPROTOBUF_EXPORT VersionString(int version); typedef unsigned int uint; #ifdef _MSC_VER -typedef __int8 int8; +typedef signed __int8 int8; typedef __int16 int16; typedef __int32 int32; typedef __int64 int64; @@ -1133,6 +1141,14 @@ class LIBPROTOBUF_EXPORT Mutex { GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Mutex); }; +// Undefine the macros to workaround the conflicts with Google internal +// MutexLock implementation. +// TODO(liujisi): Remove the undef once internal macros are removed. +#undef MutexLock +#undef ReaderMutexLock +#undef WriterMutexLock +#undef MutexLockMaybe + // MutexLock(mu) acquires mu when constructed and releases it when destroyed. class LIBPROTOBUF_EXPORT MutexLock { public: @@ -1158,6 +1174,38 @@ class LIBPROTOBUF_EXPORT MutexLockMaybe { GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MutexLockMaybe); }; +#if defined(__ANDROID__) || defined(GOOGLE_PROTOBUF_OS_ANDROID) || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || defined(GOOGLE_PROTOBUF_OS_IPHONE) +// 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 also does not support the __thread keyword. +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 == NULL) { + 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, diff --git a/src/google/protobuf/stubs/hash.h b/src/google/protobuf/stubs/hash.h index 82d5052e..4da8a5d8 100755 --- a/src/google/protobuf/stubs/hash.h +++ b/src/google/protobuf/stubs/hash.h @@ -53,6 +53,7 @@ namespace google { namespace protobuf { #ifdef GOOGLE_PROTOBUF_MISSING_HASH +#undef GOOGLE_PROTOBUF_MISSING_HASH // This system doesn't have hash_map or hash_set. Emulate them using map and // set. @@ -92,9 +93,12 @@ template <typename Key, typename Data, typename EqualKey = std::equal_to<Key>, typename Alloc = std::allocator< std::pair<const Key, Data> > > class hash_map : public std::map<Key, Data, HashFcn, EqualKey, Alloc> { + typedef std::map<Key, Data, HashFcn, EqualKey, Alloc> BaseClass; + public: - hash_map(int = 0, const HashFcn& = HashFcn(), const EqualKey& = EqualKey(), - const Alloc& = Alloc()) {} + hash_map(int a = 0, const HashFcn& b = HashFcn(), + const EqualKey& c = EqualKey(), + const Alloc& d = Alloc()) : BaseClass(a, b, c, d) {} }; template <typename Key, @@ -108,7 +112,7 @@ class hash_set : public std::set<Key, HashFcn> { #elif defined(_MSC_VER) && !defined(_STLPORT_VERSION) template <typename Key> -struct hash : public GOOGLE_PROTOBUF_HASH_NAMESPACE::hash_compare<Key> { +struct hash : public GOOGLE_PROTOBUF_HASH_COMPARE<Key> { }; // MSVC's hash_compare<const char*> hashes based on the string contents but @@ -122,8 +126,7 @@ class CstringLess { template <> struct hash<const char*> - : public GOOGLE_PROTOBUF_HASH_NAMESPACE::hash_compare< - const char*, CstringLess> {}; + : public GOOGLE_PROTOBUF_HASH_COMPARE<const char*, CstringLess> {}; template <typename Key, typename Data, typename HashFcn = hash<Key>, @@ -132,9 +135,13 @@ template <typename Key, typename Data, class hash_map : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS< Key, Data, HashFcn, EqualKey, Alloc> { + typedef GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS< + Key, Data, HashFcn, EqualKey, Alloc> BaseClass; + public: - hash_map(int = 0, const HashFcn& = HashFcn(), const EqualKey& = EqualKey(), - const Alloc& = Alloc()) {} + hash_map(int a = 0, const HashFcn& b = HashFcn(), + const EqualKey& c = EqualKey(), + const Alloc& d = Alloc()) : BaseClass(a, b, c, d) {} }; template <typename Key, typename HashFcn = hash<Key>, @@ -172,6 +179,13 @@ struct hash<const char*> { } }; +template<> +struct hash<bool> { + size_t operator()(bool x) const { + return static_cast<size_t>(x); + } +}; + template <typename Key, typename Data, typename HashFcn = hash<Key>, typename EqualKey = std::equal_to<Key>, @@ -179,9 +193,13 @@ template <typename Key, typename Data, class hash_map : public GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS< Key, Data, HashFcn, EqualKey, Alloc> { + typedef GOOGLE_PROTOBUF_HASH_NAMESPACE::GOOGLE_PROTOBUF_HASH_MAP_CLASS< + Key, Data, HashFcn, EqualKey, Alloc> BaseClass; + public: - hash_map(int = 0, const HashFcn& = HashFcn(), const EqualKey& = EqualKey(), - const Alloc& = Alloc()) {} + hash_map(int a = 0, const HashFcn& b = HashFcn(), + const EqualKey& c = EqualKey(), + const Alloc& d = Alloc()) : BaseClass(a, b, c, d) {} }; template <typename Key, typename HashFcn = hash<Key>, @@ -193,7 +211,6 @@ class hash_set hash_set(int = 0) {} }; -#undef GOOGLE_PROTOBUF_MISSING_HASH #endif // !GOOGLE_PROTOBUF_MISSING_HASH template <> @@ -204,7 +221,7 @@ struct hash<string> { static const size_t bucket_size = 4; static const size_t min_buckets = 8; - inline size_t operator()(const string& a, const string& b) const { + inline bool operator()(const string& a, const string& b) const { return a < b; } }; @@ -222,7 +239,7 @@ struct hash<pair<First, Second> > { static const size_t bucket_size = 4; static const size_t min_buckets = 8; - inline size_t operator()(const pair<First, Second>& a, + inline bool operator()(const pair<First, Second>& a, const pair<First, Second>& b) const { return a < b; } diff --git a/src/google/protobuf/stubs/platform_macros.h b/src/google/protobuf/stubs/platform_macros.h index 1ff09b83..2ce7fc8f 100644 --- a/src/google/protobuf/stubs/platform_macros.h +++ b/src/google/protobuf/stubs/platform_macros.h @@ -95,12 +95,18 @@ GOOGLE_PROTOBUF_PLATFORM_ERROR #if defined(__APPLE__) #define GOOGLE_PROTOBUF_OS_APPLE +#include <TargetConditionals.h> +#if TARGET_OS_IPHONE +#define GOOGLE_PROTOBUF_OS_IPHONE +#endif #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 diff --git a/src/google/protobuf/stubs/strutil.cc b/src/google/protobuf/stubs/strutil.cc index 7955d261..7ecc17ee 100644 --- a/src/google/protobuf/stubs/strutil.cc +++ b/src/google/protobuf/stubs/strutil.cc @@ -1285,24 +1285,6 @@ char* FloatToBuffer(float value, char* buffer) { return buffer; } -string ToHex(uint64 num) { - if (num == 0) { - return string("0"); - } - - // Compute hex bytes in reverse order, writing to the back of the - // buffer. - char buf[16]; // No more than 16 hex digits needed. - char* bufptr = buf + 16; - static const char kHexChars[] = "0123456789abcdef"; - while (num != 0) { - *--bufptr = kHexChars[num & 0xf]; - num >>= 4; - } - - return string(bufptr, buf + 16 - bufptr); -} - namespace strings { AlphaNum::AlphaNum(strings::Hex hex) { diff --git a/src/google/protobuf/stubs/strutil.h b/src/google/protobuf/stubs/strutil.h index 920701eb..397122ef 100644 --- a/src/google/protobuf/stubs/strutil.h +++ b/src/google/protobuf/stubs/strutil.h @@ -534,7 +534,7 @@ struct Hex { } }; -struct AlphaNum { +struct LIBPROTOBUF_EXPORT AlphaNum { const char *piece_data_; // move these to string_ref eventually size_t piece_size_; // move these to string_ref eventually @@ -610,23 +610,30 @@ using strings::AlphaNum; // be a reference into str. // ---------------------------------------------------------------------- -string StrCat(const AlphaNum &a, const AlphaNum &b); -string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c); -string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, - const AlphaNum &d); -string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, - const AlphaNum &d, const AlphaNum &e); -string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, - const AlphaNum &d, const AlphaNum &e, const AlphaNum &f); -string StrCat(const AlphaNum &a, const AlphaNum &b, const AlphaNum &c, - const AlphaNum &d, const AlphaNum &e, const AlphaNum &f, - const AlphaNum &g); -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); -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); +LIBPROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b); +LIBPROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c); +LIBPROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d); +LIBPROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d, + const AlphaNum& e); +LIBPROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d, + const AlphaNum& e, const AlphaNum& f); +LIBPROTOBUF_EXPORT string StrCat(const AlphaNum& a, const AlphaNum& b, + const AlphaNum& c, const AlphaNum& d, + const AlphaNum& e, const AlphaNum& f, + const AlphaNum& g); +LIBPROTOBUF_EXPORT 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); +LIBPROTOBUF_EXPORT 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 string StrCat(const AlphaNum& a) { return string(a.data(), a.size()); } @@ -651,12 +658,14 @@ inline string StrCat(const AlphaNum& a) { return string(a.data(), a.size()); } // worked around as consecutive calls to StrAppend are quite efficient. // ---------------------------------------------------------------------- -void StrAppend(string* dest, const AlphaNum& a); -void StrAppend(string* dest, const AlphaNum& a, const AlphaNum& b); -void StrAppend(string* dest, const AlphaNum& a, const AlphaNum& b, - const AlphaNum& c); -void StrAppend(string* dest, const AlphaNum& a, const AlphaNum& b, - const AlphaNum& c, const AlphaNum& d); +LIBPROTOBUF_EXPORT void StrAppend(string* dest, const AlphaNum& a); +LIBPROTOBUF_EXPORT void StrAppend(string* dest, const AlphaNum& a, + const AlphaNum& b); +LIBPROTOBUF_EXPORT void StrAppend(string* dest, const AlphaNum& a, + const AlphaNum& b, const AlphaNum& c); +LIBPROTOBUF_EXPORT void StrAppend(string* dest, const AlphaNum& a, + const AlphaNum& b, const AlphaNum& c, + const AlphaNum& d); // ---------------------------------------------------------------------- // Join() @@ -683,12 +692,6 @@ string Join(const Range& components, } // ---------------------------------------------------------------------- -// ToHex() -// Return a lower-case hex string representation of the given integer. -// ---------------------------------------------------------------------- -LIBPROTOBUF_EXPORT 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. diff --git a/src/google/protobuf/stubs/type_traits.h b/src/google/protobuf/stubs/type_traits.h index b58cae3f..36a8f3b1 100644 --- a/src/google/protobuf/stubs/type_traits.h +++ b/src/google/protobuf/stubs/type_traits.h @@ -73,6 +73,10 @@ struct is_base_of { typedef char (&yes)[1]; typedef char (&no)[2]; + // BEGIN GOOGLE LOCAL MODIFICATION -- check is a #define on Mac. + #undef check + // END GOOGLE LOCAL MODIFICATION + static yes check(const B*); static no check(const void*); diff --git a/src/google/protobuf/testdata/golden_message_proto3 b/src/google/protobuf/testdata/golden_message_proto3 Binary files differindex 934f36fa..bd646a0d 100644 --- a/src/google/protobuf/testdata/golden_message_proto3 +++ b/src/google/protobuf/testdata/golden_message_proto3 diff --git a/src/google/protobuf/testdata/map_test_data.txt b/src/google/protobuf/testdata/map_test_data.txt new file mode 100644 index 00000000..bc272321 --- /dev/null +++ b/src/google/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/src/google/protobuf/testing/googletest.cc b/src/google/protobuf/testing/googletest.cc index d72fa5c0..64328063 100644 --- a/src/google/protobuf/testing/googletest.cc +++ b/src/google/protobuf/testing/googletest.cc @@ -65,6 +65,7 @@ namespace protobuf { #endif string TestSourceDir() { +#ifndef GOOGLE_THIRD_PARTY_PROTOBUF #ifdef _MSC_VER // Look for the "src" directory. string prefix = "."; @@ -88,6 +89,9 @@ string TestSourceDir() { return result; } #endif +#else + return "third_party/protobuf/src"; +#endif // GOOGLE_THIRD_PARTY_PROTOBUF } namespace { @@ -104,6 +108,10 @@ string GetTemporaryDirectoryName() { if (HasPrefixString(result, "\\")) { result.erase(0, 1); } + // The Win32 API accepts forward slashes as a path delimiter even though + // backslashes are standard. Let's avoid confusion and use only forward + // slashes. + result = StringReplace(result, "\\", "/", true); #endif // _WIN32 return result; } diff --git a/src/google/protobuf/text_format.cc b/src/google/protobuf/text_format.cc index ec070c51..61dfa5d6 100644 --- a/src/google/protobuf/text_format.cc +++ b/src/google/protobuf/text_format.cc @@ -43,6 +43,8 @@ #include <google/protobuf/text_format.h> #include <google/protobuf/descriptor.h> +#include <google/protobuf/dynamic_message.h> +#include <google/protobuf/repeated_field.h> #include <google/protobuf/wire_format_lite.h> #include <google/protobuf/io/coded_stream.h> #include <google/protobuf/io/zero_copy_stream.h> @@ -50,6 +52,7 @@ #include <google/protobuf/unknown_field_set.h> #include <google/protobuf/descriptor.pb.h> #include <google/protobuf/io/tokenizer.h> +#include <google/protobuf/any.h> #include <google/protobuf/stubs/stringprintf.h> #include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/map_util.h> @@ -70,6 +73,18 @@ inline bool IsOctNumber(const string& str) { (str[1] >= '0' && str[1] < '8')); } +inline bool GetAnyFieldDescriptors(const Message& message, + const FieldDescriptor** type_url_field, + const FieldDescriptor** value_field) { + const Descriptor* descriptor = message.GetDescriptor(); + *type_url_field = descriptor->FindFieldByNumber(1); + *value_field = descriptor->FindFieldByNumber(2); + return (*type_url_field != NULL && + (*type_url_field)->type() == FieldDescriptor::TYPE_STRING && + *value_field != NULL && + (*value_field)->type() == FieldDescriptor::TYPE_BYTES); +} + } // namespace string Message::DebugString() const { @@ -330,7 +345,17 @@ class TextFormat::Parser::ParserImpl { // Confirm that we have a valid ending delimiter. DO(Consume(delimiter)); + return true; + } + // Consume either "<" or "{". + bool ConsumeMessageDelimiter(string* delimiter) { + if (TryConsume("<")) { + *delimiter = ">"; + } else { + DO(Consume("{")); + *delimiter = "}"; + } return true; } @@ -347,15 +372,28 @@ class TextFormat::Parser::ParserImpl { 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("[")) { + string full_type_name; + DO(ConsumeAnyTypeUrl(&full_type_name)); + DO(Consume("]")); + string serialized_value; + DO(ConsumeAnyValue(full_type_name, + message->GetDescriptor()->file()->pool(), + &serialized_value)); + reflection->SetString( + message, any_type_url_field, + string(internal::kTypeGoogleApisComPrefix) + full_type_name); + reflection->SetString(message, any_value_field, serialized_value); + return true; + // Fall through. + } if (TryConsume("[")) { // Extension. - DO(ConsumeIdentifier(&field_name)); - while (TryConsume(".")) { - string part; - DO(ConsumeIdentifier(&part)); - field_name += "."; - field_name += part; - } + DO(ConsumeFullTypeName(&field_name)); DO(Consume("]")); field = (finder_ != NULL @@ -512,13 +550,7 @@ class TextFormat::Parser::ParserImpl { string field_name; if (TryConsume("[")) { // Extension name. - DO(ConsumeIdentifier(&field_name)); - while (TryConsume(".")) { - string part; - DO(ConsumeIdentifier(&part)); - field_name += "."; - field_name += part; - } + DO(ConsumeFullTypeName(&field_name)); DO(Consume("]")); } else { DO(ConsumeIdentifier(&field_name)); @@ -553,13 +585,7 @@ class TextFormat::Parser::ParserImpl { } string delimiter; - if (TryConsume("<")) { - delimiter = ">"; - } else { - DO(Consume("{")); - delimiter = "}"; - } - + DO(ConsumeMessageDelimiter(&delimiter)); if (field->is_repeated()) { DO(ConsumeMessage(reflection->AddMessage(message, field), delimiter)); } else { @@ -576,12 +602,7 @@ class TextFormat::Parser::ParserImpl { // the ending delimiter. bool SkipFieldMessage() { string delimiter; - if (TryConsume("<")) { - delimiter = ">"; - } else { - DO(Consume("{")); - delimiter = "}"; - } + DO(ConsumeMessageDelimiter(&delimiter)); while (!LookingAt(">") && !LookingAt("}")) { DO(SkipField()); } @@ -808,6 +829,18 @@ class TextFormat::Parser::ParserImpl { return false; } + // Consume a string of form "<id1>.<id2>....<idN>". + bool ConsumeFullTypeName(string* name) { + DO(ConsumeIdentifier(name)); + while (TryConsume(".")) { + string part; + DO(ConsumeIdentifier(&part)); + *name += "."; + *name += part; + } + return true; + } + // Consumes a string and saves its value in the text parameter. // Returns false if the token is not of type STRING. bool ConsumeString(string* text) { @@ -947,6 +980,54 @@ class TextFormat::Parser::ParserImpl { return true; } + // Consumes Any::type_url value, of form "type.googleapis.com/full.type.Name" + bool ConsumeAnyTypeUrl(string* full_type_name) { + // TODO(saito) Extend Consume() to consume multiple tokens at once, so that + // this code can be written as just DO(Consume(kGoogleApisTypePrefix)). + string url1, url2, url3; + DO(ConsumeIdentifier(&url1)); // type + DO(Consume(".")); + DO(ConsumeIdentifier(&url2)); // googleapis + DO(Consume(".")); + DO(ConsumeIdentifier(&url3)); // com + DO(Consume("/")); + DO(ConsumeFullTypeName(full_type_name)); + + const string prefix = url1 + "." + url2 + "." + url3 + "/"; + if (prefix != internal::kTypeGoogleApisComPrefix) { + ReportError("TextFormat::Parser for Any supports only " + "type.googleapi.com, but found \"" + prefix + "\""); + return false; + } + return true; + } + + // A helper function for reconstructing Any::value. Consumes a text of + // full_type_name, then serializes it into serialized_value. "pool" is used to + // look up and create a temporary object with full_type_name. + bool ConsumeAnyValue(const string& full_type_name, const DescriptorPool* pool, + string* serialized_value) { + const Descriptor* value_descriptor = + pool->FindMessageTypeByName(full_type_name); + if (value_descriptor == NULL) { + ReportError("Could not find type \"" + full_type_name + + "\" stored in google.protobuf.Any."); + return false; + } + DynamicMessageFactory factory; + const Message* value_prototype = factory.GetPrototype(value_descriptor); + if (value_prototype == NULL) { + return false; + } + google::protobuf::scoped_ptr<Message> value(value_prototype->New()); + string sub_delimiter; + DO(ConsumeMessageDelimiter(&sub_delimiter)); + DO(ConsumeMessage(value.get(), sub_delimiter)); + + 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. @@ -1338,7 +1419,8 @@ TextFormat::Printer::Printer() use_field_number_(false), use_short_repeated_primitives_(false), hide_unknown_fields_(false), - print_message_fields_in_index_order_(false) { + print_message_fields_in_index_order_(false), + expand_any_(false) { SetUseUtf8StringEscaping(false); } @@ -1413,11 +1495,63 @@ struct FieldIndexSorter { 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 string& type_url = reflection->GetString(message, type_url_field); + string full_type_name; + if (!internal::ParseAnyTypeUrl(type_url, &full_type_name)) { + return false; + } + + // Print the "value" in text. + const google::protobuf::Descriptor* value_descriptor = + message.GetDescriptor()->file()->pool()->FindMessageTypeByName( + full_type_name); + if (value_descriptor == NULL) { + GOOGLE_LOG(WARNING) << "Proto type " << type_url << " not found"; + return false; + } + DynamicMessageFactory factory; + google::protobuf::scoped_ptr<google::protobuf::Message> value_message( + factory.GetPrototype(value_descriptor)->New()); + 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.Print(StrCat("[", type_url, "]")); + const FieldValuePrinter* printer = FindWithDefault( + custom_printers_, value_field, default_field_value_printer_.get()); + generator.Print( + printer->PrintMessageStart(message, -1, 0, single_line_mode_)); + generator.Indent(); + Print(*value_message, generator); + generator.Outdent(); + generator.Print(printer->PrintMessageEnd(message, -1, 0, single_line_mode_)); + return true; +} + void TextFormat::Printer::Print(const Message& message, TextGenerator& generator) const { + const Descriptor* descriptor = message.GetDescriptor(); const Reflection* reflection = message.GetReflection(); + if (descriptor->full_name() == internal::kAnyFullTypeName && expand_any_ && + PrintAny(message, generator)) { + return; + } vector<const FieldDescriptor*> fields; reflection->ListFields(message, &fields); if (print_message_fields_in_index_order_) { @@ -1446,6 +1580,54 @@ void TextFormat::Printer::PrintFieldValueToString( 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 first = reflection->GetInt32(*a, field_); + int32 second = reflection->GetInt32(*b, field_); + return first < second; + } + case FieldDescriptor::CPPTYPE_INT64: { + int64 first = reflection->GetInt64(*a, field_); + int64 second = reflection->GetInt64(*b, field_); + return first < second; + } + case FieldDescriptor::CPPTYPE_UINT32: { + uint32 first = reflection->GetUInt32(*a, field_); + uint32 second = reflection->GetUInt32(*b, field_); + return first < second; + } + case FieldDescriptor::CPPTYPE_UINT64: { + uint64 first = reflection->GetUInt64(*a, field_); + uint64 second = reflection->GetUInt64(*b, field_); + return first < second; + } + case FieldDescriptor::CPPTYPE_STRING: { + string first = reflection->GetString(*a, field_); + string second = reflection->GetString(*b, field_); + return first < second; + } + default: + GOOGLE_LOG(DFATAL) << "Invalid key for map field."; + return true; + } + } + + private: + const FieldDescriptor* field_; +}; + void TextFormat::Printer::PrintField(const Message& message, const Reflection* reflection, const FieldDescriptor* field, @@ -1466,6 +1648,21 @@ void TextFormat::Printer::PrintField(const Message& message, count = 1; } + std::vector<const Message*> sorted_map_field; + if (field->is_map()) { + const RepeatedPtrField<Message>& map_field = + reflection->GetRepeatedPtrField<Message>(message, field); + for (RepeatedPtrField<Message>::const_pointer_iterator it = + map_field.pointer_begin(); + it != map_field.pointer_end(); ++it) { + sorted_map_field.push_back(*it); + } + + MapEntryMessageComparator comparator(field->message_type()); + std::stable_sort(sorted_map_field.begin(), sorted_map_field.end(), + comparator); + } + for (int j = 0; j < count; ++j) { const int field_index = field->is_repeated() ? j : -1; @@ -1475,8 +1672,10 @@ void TextFormat::Printer::PrintField(const Message& message, const FieldValuePrinter* printer = FindWithDefault( custom_printers_, field, default_field_value_printer_.get()); const Message& sub_message = - field->is_repeated() - ? reflection->GetRepeatedMessage(message, field, j) + field->is_repeated() + ? (field->is_map() + ? *sorted_map_field[j] + : reflection->GetRepeatedMessage(message, field, j)) : reflection->GetMessage(message, field); generator.Print( printer->PrintMessageStart( @@ -1680,8 +1879,8 @@ void TextFormat::Printer::PrintUnknownFields( case UnknownField::TYPE_FIXED32: { generator.Print(field_number); generator.Print(": 0x"); - char buffer[kFastToBufferSize]; - generator.Print(FastHex32ToBuffer(field.fixed32(), buffer)); + generator.Print( + StrCat(strings::Hex(field.fixed32(), strings::Hex::ZERO_PAD_8))); if (single_line_mode_) { generator.Print(" "); } else { @@ -1692,8 +1891,8 @@ void TextFormat::Printer::PrintUnknownFields( case UnknownField::TYPE_FIXED64: { generator.Print(field_number); generator.Print(": 0x"); - char buffer[kFastToBufferSize]; - generator.Print(FastHex64ToBuffer(field.fixed64(), buffer)); + generator.Print( + StrCat(strings::Hex(field.fixed64(), strings::Hex::ZERO_PAD_16))); if (single_line_mode_) { generator.Print(" "); } else { diff --git a/src/google/protobuf/text_format.h b/src/google/protobuf/text_format.h index 9e2cb070..6717aecd 100644 --- a/src/google/protobuf/text_format.h +++ b/src/google/protobuf/text_format.h @@ -208,6 +208,17 @@ class LIBPROTOBUF_EXPORT TextFormat { 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; + } + // Register a custom field-specific FieldValuePrinter for fields // with a particular FieldDescriptor. // Returns "true" if the registration succeeded, or "false", if there is @@ -259,6 +270,8 @@ class LIBPROTOBUF_EXPORT TextFormat { void PrintUnknownFields(const UnknownFieldSet& unknown_fields, TextGenerator& generator) const; + bool PrintAny(const Message& message, TextGenerator& generator) const; + int initial_indent_level_; bool single_line_mode_; @@ -271,6 +284,8 @@ class LIBPROTOBUF_EXPORT TextFormat { bool print_message_fields_in_index_order_; + bool expand_any_; + google::protobuf::scoped_ptr<const FieldValuePrinter> default_field_value_printer_; typedef map<const FieldDescriptor*, const FieldValuePrinter*> CustomPrinterMap; diff --git a/src/google/protobuf/text_format_unittest.cc b/src/google/protobuf/text_format_unittest.cc index 477fdcbd..1b18c5ed 100644 --- a/src/google/protobuf/text_format_unittest.cc +++ b/src/google/protobuf/text_format_unittest.cc @@ -32,23 +32,24 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. +#include <google/protobuf/text_format.h> + #include <math.h> #include <stdlib.h> #include <limits> -#include <google/protobuf/text_format.h> -#include <google/protobuf/io/zero_copy_stream_impl.h> -#include <google/protobuf/io/tokenizer.h> -#include <google/protobuf/unittest.pb.h> -#include <google/protobuf/unittest_mset.pb.h> -#include <google/protobuf/test_util.h> - #include <google/protobuf/stubs/common.h> #include <google/protobuf/testing/file.h> -#include <google/protobuf/testing/googletest.h> -#include <gtest/gtest.h> +#include <google/protobuf/test_util.h> +#include <google/protobuf/unittest.pb.h> +#include <google/protobuf/unittest_mset.pb.h> +#include <google/protobuf/io/tokenizer.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> #include <google/protobuf/stubs/strutil.h> #include <google/protobuf/stubs/substitute.h> +#include <google/protobuf/testing/googletest.h> +#include <gtest/gtest.h> + namespace google { namespace protobuf { @@ -451,7 +452,7 @@ TEST_F(TextFormatTest, ErrorCasesRegisteringFieldValuePrinterShouldFail) { class CustomMessageFieldValuePrinter : public TextFormat::FieldValuePrinter { public: virtual string PrintInt32(int32 v) const { - return StrCat(FieldValuePrinter::PrintInt32(v), " # x", ToHex(v)); + return StrCat(FieldValuePrinter::PrintInt32(v), " # x", strings::Hex(v)); } virtual string PrintMessageStart(const Message& message, diff --git a/src/google/protobuf/timestamp.pb.cc b/src/google/protobuf/timestamp.pb.cc new file mode 100644 index 00000000..877dc8f3 --- /dev/null +++ b/src/google/protobuf/timestamp.pb.cc @@ -0,0 +1,407 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/timestamp.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "google/protobuf/timestamp.pb.h" + +#include <algorithm> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/once.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/wire_format_lite_inl.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/reflection_ops.h> +#include <google/protobuf/wire_format.h> +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { + +namespace { + +const ::google::protobuf::Descriptor* Timestamp_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Timestamp_reflection_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_google_2fprotobuf_2ftimestamp_2eproto() { + protobuf_AddDesc_google_2fprotobuf_2ftimestamp_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "google/protobuf/timestamp.proto"); + GOOGLE_CHECK(file != NULL); + Timestamp_descriptor_ = file->message_type(0); + static const int Timestamp_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Timestamp, seconds_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Timestamp, nanos_), + }; + Timestamp_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + Timestamp_descriptor_, + Timestamp::default_instance_, + Timestamp_offsets_, + -1, + -1, + -1, + sizeof(Timestamp), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Timestamp, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Timestamp, _is_default_instance_)); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_google_2fprotobuf_2ftimestamp_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Timestamp_descriptor_, &Timestamp::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_google_2fprotobuf_2ftimestamp_2eproto() { + delete Timestamp::default_instance_; + delete Timestamp_reflection_; +} + +void protobuf_AddDesc_google_2fprotobuf_2ftimestamp_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\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(\005BI\n\023com.google.protobufB\016" + "TimestampProtoP\001\240\001\001\242\002\003GPB\252\002\026Google.Proto" + "colBuffersb\006proto3", 178); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "google/protobuf/timestamp.proto", &protobuf_RegisterTypes); + Timestamp::default_instance_ = new Timestamp(); + Timestamp::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_google_2fprotobuf_2ftimestamp_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_google_2fprotobuf_2ftimestamp_2eproto { + StaticDescriptorInitializer_google_2fprotobuf_2ftimestamp_2eproto() { + protobuf_AddDesc_google_2fprotobuf_2ftimestamp_2eproto(); + } +} static_descriptor_initializer_google_2fprotobuf_2ftimestamp_2eproto_; + +namespace { + +static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD; +static void MergeFromFail(int line) { + GOOGLE_CHECK(false) << __FILE__ << ":" << line; +} + +} // namespace + + +// =================================================================== + +#ifndef _MSC_VER +const int Timestamp::kSecondsFieldNumber; +const int Timestamp::kNanosFieldNumber; +#endif // !_MSC_VER + +Timestamp::Timestamp() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:google.protobuf.Timestamp) +} + +void Timestamp::InitAsDefaultInstance() { + _is_default_instance_ = true; +} + +Timestamp::Timestamp(const Timestamp& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:google.protobuf.Timestamp) +} + +void Timestamp::SharedCtor() { + _is_default_instance_ = false; + _cached_size_ = 0; + seconds_ = GOOGLE_LONGLONG(0); + nanos_ = 0; +} + +Timestamp::~Timestamp() { + // @@protoc_insertion_point(destructor:google.protobuf.Timestamp) + SharedDtor(); +} + +void Timestamp::SharedDtor() { + if (this != default_instance_) { + } +} + +void Timestamp::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Timestamp::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Timestamp_descriptor_; +} + +const Timestamp& Timestamp::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2ftimestamp_2eproto(); + return *default_instance_; +} + +Timestamp* Timestamp::default_instance_ = NULL; + +Timestamp* Timestamp::New(::google::protobuf::Arena* arena) const { + Timestamp* n = new Timestamp; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void Timestamp::Clear() { +#define ZR_HELPER_(f) reinterpret_cast<char*>(\ + &reinterpret_cast<Timestamp*>(16)->f) + +#define ZR_(first, last) do {\ + ::memset(&first, 0,\ + ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\ +} while (0) + + ZR_(seconds_, nanos_); + +#undef ZR_HELPER_ +#undef ZR_ + +} + +bool Timestamp::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:google.protobuf.Timestamp) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional int64 seconds = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( + input, &seconds_))); + + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_nanos; + break; + } + + // optional int32 nanos = 2; + case 2: { + if (tag == 16) { + parse_nanos: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &nanos_))); + + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:google.protobuf.Timestamp) + return true; +failure: + // @@protoc_insertion_point(parse_failure:google.protobuf.Timestamp) + return false; +#undef DO_ +} + +void Timestamp::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:google.protobuf.Timestamp) + // optional int64 seconds = 1; + if (this->seconds() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteInt64(1, this->seconds(), output); + } + + // optional int32 nanos = 2; + if (this->nanos() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->nanos(), output); + } + + // @@protoc_insertion_point(serialize_end:google.protobuf.Timestamp) +} + +::google::protobuf::uint8* Timestamp::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Timestamp) + // optional int64 seconds = 1; + if (this->seconds() != 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(1, this->seconds(), target); + } + + // optional int32 nanos = 2; + if (this->nanos() != 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->nanos(), target); + } + + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Timestamp) + return target; +} + +int Timestamp::ByteSize() const { + int total_size = 0; + + // optional int64 seconds = 1; + if (this->seconds() != 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int64Size( + this->seconds()); + } + + // optional int32 nanos = 2; + if (this->nanos() != 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->nanos()); + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Timestamp::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const Timestamp* source = + ::google::protobuf::internal::DynamicCastToGenerated<const Timestamp>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Timestamp::MergeFrom(const Timestamp& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from.seconds() != 0) { + set_seconds(from.seconds()); + } + if (from.nanos() != 0) { + set_nanos(from.nanos()); + } +} + +void Timestamp::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Timestamp::CopyFrom(const Timestamp& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Timestamp::IsInitialized() const { + + return true; +} + +void Timestamp::Swap(Timestamp* other) { + if (other == this) return; + InternalSwap(other); +} +void Timestamp::InternalSwap(Timestamp* other) { + std::swap(seconds_, other->seconds_); + std::swap(nanos_, other->nanos_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata Timestamp::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Timestamp_descriptor_; + metadata.reflection = Timestamp_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// Timestamp + +// optional int64 seconds = 1; +void Timestamp::clear_seconds() { + seconds_ = GOOGLE_LONGLONG(0); +} + ::google::protobuf::int64 Timestamp::seconds() const { + // @@protoc_insertion_point(field_get:google.protobuf.Timestamp.seconds) + return seconds_; +} + void Timestamp::set_seconds(::google::protobuf::int64 value) { + + seconds_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Timestamp.seconds) +} + +// optional int32 nanos = 2; +void Timestamp::clear_nanos() { + nanos_ = 0; +} + ::google::protobuf::int32 Timestamp::nanos() const { + // @@protoc_insertion_point(field_get:google.protobuf.Timestamp.nanos) + return nanos_; +} + void Timestamp::set_nanos(::google::protobuf::int32 value) { + + nanos_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Timestamp.nanos) +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// @@protoc_insertion_point(namespace_scope) + +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) diff --git a/src/google/protobuf/timestamp.pb.h b/src/google/protobuf/timestamp.pb.h new file mode 100644 index 00000000..85fc1242 --- /dev/null +++ b/src/google/protobuf/timestamp.pb.h @@ -0,0 +1,172 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/timestamp.proto + +#ifndef PROTOBUF_google_2fprotobuf_2ftimestamp_2eproto__INCLUDED +#define PROTOBUF_google_2fprotobuf_2ftimestamp_2eproto__INCLUDED + +#include <string> + +#include <google/protobuf/stubs/common.h> + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#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 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include <google/protobuf/arena.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/metadata.h> +#include <google/protobuf/message.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/unknown_field_set.h> +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { + +// Internal implementation detail -- do not call these. +void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ftimestamp_2eproto(); +void protobuf_AssignDesc_google_2fprotobuf_2ftimestamp_2eproto(); +void protobuf_ShutdownFile_google_2fprotobuf_2ftimestamp_2eproto(); + +class Timestamp; + +// =================================================================== + +class LIBPROTOBUF_EXPORT Timestamp : public ::google::protobuf::Message { + public: + Timestamp(); + virtual ~Timestamp(); + + Timestamp(const Timestamp& from); + + inline Timestamp& operator=(const Timestamp& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Timestamp& default_instance(); + + void Swap(Timestamp* other); + + // implements Message ---------------------------------------------- + + inline Timestamp* New() const { return New(NULL); } + + Timestamp* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Timestamp& from); + void MergeFrom(const Timestamp& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Timestamp* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional int64 seconds = 1; + void clear_seconds(); + static const int kSecondsFieldNumber = 1; + ::google::protobuf::int64 seconds() const; + void set_seconds(::google::protobuf::int64 value); + + // optional int32 nanos = 2; + void clear_nanos(); + static const int kNanosFieldNumber = 2; + ::google::protobuf::int32 nanos() const; + void set_nanos(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:google.protobuf.Timestamp) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::int64 seconds_; + ::google::protobuf::int32 nanos_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ftimestamp_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2ftimestamp_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2ftimestamp_2eproto(); + + void InitAsDefaultInstance(); + static Timestamp* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// Timestamp + +// optional int64 seconds = 1; +inline void Timestamp::clear_seconds() { + seconds_ = GOOGLE_LONGLONG(0); +} +inline ::google::protobuf::int64 Timestamp::seconds() const { + // @@protoc_insertion_point(field_get:google.protobuf.Timestamp.seconds) + return seconds_; +} +inline void Timestamp::set_seconds(::google::protobuf::int64 value) { + + seconds_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Timestamp.seconds) +} + +// optional int32 nanos = 2; +inline void Timestamp::clear_nanos() { + nanos_ = 0; +} +inline ::google::protobuf::int32 Timestamp::nanos() const { + // @@protoc_insertion_point(field_get:google.protobuf.Timestamp.nanos) + return nanos_; +} +inline void Timestamp::set_nanos(::google::protobuf::int32 value) { + + nanos_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Timestamp.nanos) +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS + +// @@protoc_insertion_point(namespace_scope) + +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_google_2fprotobuf_2ftimestamp_2eproto__INCLUDED diff --git a/src/google/protobuf/timestamp.proto b/src/google/protobuf/timestamp.proto index 89956229..381ff997 100644 --- a/src/google/protobuf/timestamp.proto +++ b/src/google/protobuf/timestamp.proto @@ -35,6 +35,8 @@ option java_generate_equals_and_hash = true; option java_multiple_files = true; option java_outer_classname = "TimestampProto"; option java_package = "com.google.protobuf"; +option csharp_namespace = "Google.ProtocolBuffers"; +option objc_class_prefix = "GPB"; // A Timestamp represents a point in time independent of any time zone diff --git a/src/google/protobuf/type.pb.cc b/src/google/protobuf/type.pb.cc new file mode 100644 index 00000000..8b08909e --- /dev/null +++ b/src/google/protobuf/type.pb.cc @@ -0,0 +1,2899 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/type.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "google/protobuf/type.pb.h" + +#include <algorithm> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/once.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/wire_format_lite_inl.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/reflection_ops.h> +#include <google/protobuf/wire_format.h> +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { + +namespace { + +const ::google::protobuf::Descriptor* Type_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Type_reflection_ = NULL; +const ::google::protobuf::Descriptor* Field_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Field_reflection_ = NULL; +const ::google::protobuf::EnumDescriptor* Field_Kind_descriptor_ = NULL; +const ::google::protobuf::EnumDescriptor* Field_Cardinality_descriptor_ = NULL; +const ::google::protobuf::Descriptor* Enum_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Enum_reflection_ = NULL; +const ::google::protobuf::Descriptor* EnumValue_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + EnumValue_reflection_ = NULL; +const ::google::protobuf::Descriptor* Option_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Option_reflection_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto() { + protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "google/protobuf/type.proto"); + GOOGLE_CHECK(file != NULL); + Type_descriptor_ = file->message_type(0); + static const int Type_offsets_[5] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, fields_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, oneofs_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, options_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, source_context_), + }; + Type_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + Type_descriptor_, + Type::default_instance_, + Type_offsets_, + -1, + -1, + -1, + sizeof(Type), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, _is_default_instance_)); + Field_descriptor_ = file->message_type(1); + static const int Field_offsets_[8] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, kind_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, cardinality_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, number_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, type_url_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, oneof_index_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, packed_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, options_), + }; + Field_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + Field_descriptor_, + Field::default_instance_, + Field_offsets_, + -1, + -1, + -1, + sizeof(Field), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, _is_default_instance_)); + Field_Kind_descriptor_ = Field_descriptor_->enum_type(0); + Field_Cardinality_descriptor_ = Field_descriptor_->enum_type(1); + Enum_descriptor_ = file->message_type(2); + static const int Enum_offsets_[4] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, enumvalue_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, options_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, source_context_), + }; + Enum_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + Enum_descriptor_, + Enum::default_instance_, + Enum_offsets_, + -1, + -1, + -1, + sizeof(Enum), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, _is_default_instance_)); + EnumValue_descriptor_ = file->message_type(3); + static const int EnumValue_offsets_[3] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValue, name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValue, number_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValue, options_), + }; + EnumValue_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + EnumValue_descriptor_, + EnumValue::default_instance_, + EnumValue_offsets_, + -1, + -1, + -1, + sizeof(EnumValue), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValue, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValue, _is_default_instance_)); + Option_descriptor_ = file->message_type(4); + static const int Option_offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Option, name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Option, value_), + }; + Option_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + Option_descriptor_, + Option::default_instance_, + Option_offsets_, + -1, + -1, + -1, + sizeof(Option), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Option, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Option, _is_default_instance_)); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Type_descriptor_, &Type::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Field_descriptor_, &Field::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Enum_descriptor_, &Enum::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + EnumValue_descriptor_, &EnumValue::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Option_descriptor_, &Option::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_google_2fprotobuf_2ftype_2eproto() { + delete Type::default_instance_; + delete Type_reflection_; + delete Field::default_instance_; + delete Field_reflection_; + delete Enum::default_instance_; + delete Enum_reflection_; + delete EnumValue::default_instance_; + delete EnumValue_reflection_; + delete Option::default_instance_; + delete Option_reflection_; +} + +void protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::protobuf_AddDesc_google_2fprotobuf_2fany_2eproto(); + ::google::protobuf::protobuf_AddDesc_google_2fprotobuf_2fsource_5fcontext_2eproto(); + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\n\032google/protobuf/type.proto\022\017google.pro" + "tobuf\032\031google/protobuf/any.proto\032$google" + "/protobuf/source_context.proto\"\256\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\"\233\005\n\005Field\022)\n\004kind\030\001 \001(\0162\033.google" + ".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.Op" + "tion\"\270\002\n\004Kind\022\020\n\014TYPE_UNKNOWN\020\000\022\017\n\013TYPE_" + "DOUBLE\020\001\022\016\n\nTYPE_FLOAT\020\002\022\016\n\nTYPE_INT64\020\003" + "\022\017\n\013TYPE_UINT64\020\004\022\016\n\nTYPE_INT32\020\005\022\020\n\014TYP" + "E_FIXED64\020\006\022\020\n\014TYPE_FIXED32\020\007\022\r\n\tTYPE_BO" + "OL\020\010\022\017\n\013TYPE_STRING\020\t\022\020\n\014TYPE_MESSAGE\020\013\022" + "\016\n\nTYPE_BYTES\020\014\022\017\n\013TYPE_UINT32\020\r\022\r\n\tTYPE" + "_ENUM\020\016\022\021\n\rTYPE_SFIXED32\020\017\022\021\n\rTYPE_SFIXE" + "D64\020\020\022\017\n\013TYPE_SINT32\020\021\022\017\n\013TYPE_SINT64\020\022\"" + "t\n\013Cardinality\022\027\n\023CARDINALITY_UNKNOWN\020\000\022" + "\030\n\024CARDINALITY_OPTIONAL\020\001\022\030\n\024CARDINALITY" + "_REQUIRED\020\002\022\030\n\024CARDINALITY_REPEATED\020\003\"\245\001" + "\n\004Enum\022\014\n\004name\030\001 \001(\t\022-\n\tenumvalue\030\002 \003(\0132" + "\032.google.protobuf.EnumValue\022(\n\007options\030\003" + " \003(\0132\027.google.protobuf.Option\0226\n\016source_" + "context\030\004 \001(\0132\036.google.protobuf.SourceCo" + "ntext\"S\n\tEnumValue\022\014\n\004name\030\001 \001(\t\022\016\n\006numb" + "er\030\002 \001(\005\022(\n\007options\030\003 \003(\0132\027.google.proto" + "buf.Option\";\n\006Option\022\014\n\004name\030\001 \001(\t\022#\n\005va" + "lue\030\002 \001(\0132\024.google.protobuf.AnyB(\n\023com.g" + "oogle.protobufB\tTypeProtoP\001\242\002\003GPBb\006proto" + "3", 1321); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "google/protobuf/type.proto", &protobuf_RegisterTypes); + Type::default_instance_ = new Type(); + Field::default_instance_ = new Field(); + Enum::default_instance_ = new Enum(); + EnumValue::default_instance_ = new EnumValue(); + Option::default_instance_ = new Option(); + Type::default_instance_->InitAsDefaultInstance(); + Field::default_instance_->InitAsDefaultInstance(); + Enum::default_instance_->InitAsDefaultInstance(); + EnumValue::default_instance_->InitAsDefaultInstance(); + Option::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_google_2fprotobuf_2ftype_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_google_2fprotobuf_2ftype_2eproto { + StaticDescriptorInitializer_google_2fprotobuf_2ftype_2eproto() { + protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto(); + } +} static_descriptor_initializer_google_2fprotobuf_2ftype_2eproto_; + +namespace { + +static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD; +static void MergeFromFail(int line) { + GOOGLE_CHECK(false) << __FILE__ << ":" << line; +} + +} // namespace + + +// =================================================================== + +#ifndef _MSC_VER +const int Type::kNameFieldNumber; +const int Type::kFieldsFieldNumber; +const int Type::kOneofsFieldNumber; +const int Type::kOptionsFieldNumber; +const int Type::kSourceContextFieldNumber; +#endif // !_MSC_VER + +Type::Type() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:google.protobuf.Type) +} + +void Type::InitAsDefaultInstance() { + _is_default_instance_ = true; + source_context_ = const_cast< ::google::protobuf::SourceContext*>(&::google::protobuf::SourceContext::default_instance()); +} + +Type::Type(const Type& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:google.protobuf.Type) +} + +void Type::SharedCtor() { + _is_default_instance_ = false; + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + source_context_ = NULL; +} + +Type::~Type() { + // @@protoc_insertion_point(destructor:google.protobuf.Type) + SharedDtor(); +} + +void Type::SharedDtor() { + name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (this != default_instance_) { + delete source_context_; + } +} + +void Type::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Type::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Type_descriptor_; +} + +const Type& Type::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto(); + return *default_instance_; +} + +Type* Type::default_instance_ = NULL; + +Type* Type::New(::google::protobuf::Arena* arena) const { + Type* n = new Type; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void Type::Clear() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (GetArenaNoVirtual() == NULL && source_context_ != NULL) delete source_context_; + source_context_ = NULL; + fields_.Clear(); + oneofs_.Clear(); + options_.Clear(); +} + +bool Type::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:google.protobuf.Type) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string name = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "google.protobuf.Type.name"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_fields; + break; + } + + // repeated .google.protobuf.Field fields = 2; + case 2: { + if (tag == 18) { + parse_fields: + DO_(input->IncrementRecursionDepth()); + parse_loop_fields: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + input, add_fields())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_loop_fields; + input->UnsafeDecrementRecursionDepth(); + if (input->ExpectTag(26)) goto parse_oneofs; + break; + } + + // repeated string oneofs = 3; + case 3: { + if (tag == 26) { + parse_oneofs: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->add_oneofs())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->oneofs(this->oneofs_size() - 1).data(), + this->oneofs(this->oneofs_size() - 1).length(), + ::google::protobuf::internal::WireFormat::PARSE, + "google.protobuf.Type.oneofs"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(26)) goto parse_oneofs; + if (input->ExpectTag(34)) goto parse_options; + break; + } + + // repeated .google.protobuf.Option options = 4; + case 4: { + if (tag == 34) { + parse_options: + DO_(input->IncrementRecursionDepth()); + parse_loop_options: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + input, add_options())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(34)) goto parse_loop_options; + input->UnsafeDecrementRecursionDepth(); + if (input->ExpectTag(42)) goto parse_source_context; + break; + } + + // optional .google.protobuf.SourceContext source_context = 5; + case 5: { + if (tag == 42) { + parse_source_context: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_source_context())); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:google.protobuf.Type) + return true; +failure: + // @@protoc_insertion_point(parse_failure:google.protobuf.Type) + return false; +#undef DO_ +} + +void Type::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:google.protobuf.Type) + // optional string name = 1; + if (this->name().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.Type.name"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->name(), output); + } + + // repeated .google.protobuf.Field fields = 2; + for (unsigned int i = 0, n = this->fields_size(); i < n; i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->fields(i), output); + } + + // repeated string oneofs = 3; + for (int i = 0; i < this->oneofs_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->oneofs(i).data(), this->oneofs(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.Type.oneofs"); + ::google::protobuf::internal::WireFormatLite::WriteString( + 3, this->oneofs(i), output); + } + + // repeated .google.protobuf.Option options = 4; + for (unsigned int i = 0, n = this->options_size(); i < n; i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 4, this->options(i), output); + } + + // optional .google.protobuf.SourceContext source_context = 5; + if (this->has_source_context()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 5, *this->source_context_, output); + } + + // @@protoc_insertion_point(serialize_end:google.protobuf.Type) +} + +::google::protobuf::uint8* Type::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Type) + // optional string name = 1; + if (this->name().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.Type.name"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); + } + + // repeated .google.protobuf.Field fields = 2; + for (unsigned int i = 0, n = this->fields_size(); i < n; i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->fields(i), target); + } + + // repeated string oneofs = 3; + for (int i = 0; i < this->oneofs_size(); i++) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->oneofs(i).data(), this->oneofs(i).length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.Type.oneofs"); + target = ::google::protobuf::internal::WireFormatLite:: + WriteStringToArray(3, this->oneofs(i), target); + } + + // repeated .google.protobuf.Option options = 4; + for (unsigned int i = 0, n = this->options_size(); i < n; i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 4, this->options(i), target); + } + + // optional .google.protobuf.SourceContext source_context = 5; + if (this->has_source_context()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 5, *this->source_context_, target); + } + + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Type) + return target; +} + +int Type::ByteSize() const { + int total_size = 0; + + // optional string name = 1; + if (this->name().size() > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + // optional .google.protobuf.SourceContext source_context = 5; + if (this->has_source_context()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + *this->source_context_); + } + + // repeated .google.protobuf.Field fields = 2; + total_size += 1 * this->fields_size(); + for (int i = 0; i < this->fields_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->fields(i)); + } + + // repeated string oneofs = 3; + total_size += 1 * this->oneofs_size(); + for (int i = 0; i < this->oneofs_size(); i++) { + total_size += ::google::protobuf::internal::WireFormatLite::StringSize( + this->oneofs(i)); + } + + // repeated .google.protobuf.Option options = 4; + total_size += 1 * this->options_size(); + for (int i = 0; i < this->options_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->options(i)); + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Type::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const Type* source = + ::google::protobuf::internal::DynamicCastToGenerated<const Type>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Type::MergeFrom(const Type& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + fields_.MergeFrom(from.fields_); + oneofs_.MergeFrom(from.oneofs_); + options_.MergeFrom(from.options_); + if (from.name().size() > 0) { + + name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); + } + if (from.has_source_context()) { + mutable_source_context()->::google::protobuf::SourceContext::MergeFrom(from.source_context()); + } +} + +void Type::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Type::CopyFrom(const Type& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Type::IsInitialized() const { + + return true; +} + +void Type::Swap(Type* other) { + if (other == this) return; + InternalSwap(other); +} +void Type::InternalSwap(Type* other) { + name_.Swap(&other->name_); + fields_.UnsafeArenaSwap(&other->fields_); + oneofs_.UnsafeArenaSwap(&other->oneofs_); + options_.UnsafeArenaSwap(&other->options_); + std::swap(source_context_, other->source_context_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata Type::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Type_descriptor_; + metadata.reflection = Type_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// Type + +// optional string name = 1; +void Type::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + const ::std::string& Type::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.Type.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void Type::set_name(const ::std::string& value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Type.name) +} + void Type::set_name(const char* value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Type.name) +} + void Type::set_name(const char* value, size_t size) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Type.name) +} + ::std::string* Type::mutable_name() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Type.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* Type::release_name() { + + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void Type::set_allocated_name(::std::string* name) { + if (name != NULL) { + + } else { + + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Type.name) +} + +// repeated .google.protobuf.Field fields = 2; +int Type::fields_size() const { + return fields_.size(); +} +void Type::clear_fields() { + fields_.Clear(); +} + const ::google::protobuf::Field& Type::fields(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Type.fields) + return fields_.Get(index); +} + ::google::protobuf::Field* Type::mutable_fields(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Type.fields) + return fields_.Mutable(index); +} + ::google::protobuf::Field* Type::add_fields() { + // @@protoc_insertion_point(field_add:google.protobuf.Type.fields) + return fields_.Add(); +} + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Field >& +Type::fields() const { + // @@protoc_insertion_point(field_list:google.protobuf.Type.fields) + return fields_; +} + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Field >* +Type::mutable_fields() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Type.fields) + return &fields_; +} + +// repeated string oneofs = 3; +int Type::oneofs_size() const { + return oneofs_.size(); +} +void Type::clear_oneofs() { + oneofs_.Clear(); +} + const ::std::string& Type::oneofs(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Type.oneofs) + return oneofs_.Get(index); +} + ::std::string* Type::mutable_oneofs(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Type.oneofs) + return oneofs_.Mutable(index); +} + void Type::set_oneofs(int index, const ::std::string& value) { + // @@protoc_insertion_point(field_set:google.protobuf.Type.oneofs) + oneofs_.Mutable(index)->assign(value); +} + void Type::set_oneofs(int index, const char* value) { + oneofs_.Mutable(index)->assign(value); + // @@protoc_insertion_point(field_set_char:google.protobuf.Type.oneofs) +} + 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) +} + ::std::string* Type::add_oneofs() { + return oneofs_.Add(); +} + void Type::add_oneofs(const ::std::string& value) { + oneofs_.Add()->assign(value); + // @@protoc_insertion_point(field_add:google.protobuf.Type.oneofs) +} + void Type::add_oneofs(const char* value) { + oneofs_.Add()->assign(value); + // @@protoc_insertion_point(field_add_char:google.protobuf.Type.oneofs) +} + 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) +} + const ::google::protobuf::RepeatedPtrField< ::std::string>& +Type::oneofs() const { + // @@protoc_insertion_point(field_list:google.protobuf.Type.oneofs) + return oneofs_; +} + ::google::protobuf::RepeatedPtrField< ::std::string>* +Type::mutable_oneofs() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Type.oneofs) + return &oneofs_; +} + +// repeated .google.protobuf.Option options = 4; +int Type::options_size() const { + return options_.size(); +} +void Type::clear_options() { + options_.Clear(); +} + const ::google::protobuf::Option& Type::options(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Type.options) + return options_.Get(index); +} + ::google::protobuf::Option* Type::mutable_options(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Type.options) + return options_.Mutable(index); +} + ::google::protobuf::Option* Type::add_options() { + // @@protoc_insertion_point(field_add:google.protobuf.Type.options) + return options_.Add(); +} + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >& +Type::options() const { + // @@protoc_insertion_point(field_list:google.protobuf.Type.options) + return options_; +} + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >* +Type::mutable_options() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Type.options) + return &options_; +} + +// optional .google.protobuf.SourceContext source_context = 5; +bool Type::has_source_context() const { + return !_is_default_instance_ && source_context_ != NULL; +} +void Type::clear_source_context() { + if (GetArenaNoVirtual() == NULL && source_context_ != NULL) delete source_context_; + source_context_ = NULL; +} + const ::google::protobuf::SourceContext& Type::source_context() const { + // @@protoc_insertion_point(field_get:google.protobuf.Type.source_context) + return source_context_ != NULL ? *source_context_ : *default_instance_->source_context_; +} + ::google::protobuf::SourceContext* Type::mutable_source_context() { + + if (source_context_ == NULL) { + source_context_ = new ::google::protobuf::SourceContext; + } + // @@protoc_insertion_point(field_mutable:google.protobuf.Type.source_context) + return source_context_; +} + ::google::protobuf::SourceContext* Type::release_source_context() { + + ::google::protobuf::SourceContext* temp = source_context_; + source_context_ = NULL; + return temp; +} + void Type::set_allocated_source_context(::google::protobuf::SourceContext* source_context) { + delete source_context_; + source_context_ = source_context; + if (source_context) { + + } else { + + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Type.source_context) +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// =================================================================== + +const ::google::protobuf::EnumDescriptor* Field_Kind_descriptor() { + protobuf_AssignDescriptorsOnce(); + return Field_Kind_descriptor_; +} +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 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + return true; + default: + return false; + } +} + +#ifndef _MSC_VER +const Field_Kind Field::TYPE_UNKNOWN; +const Field_Kind Field::TYPE_DOUBLE; +const Field_Kind Field::TYPE_FLOAT; +const Field_Kind Field::TYPE_INT64; +const Field_Kind Field::TYPE_UINT64; +const Field_Kind Field::TYPE_INT32; +const Field_Kind Field::TYPE_FIXED64; +const Field_Kind Field::TYPE_FIXED32; +const Field_Kind Field::TYPE_BOOL; +const Field_Kind Field::TYPE_STRING; +const Field_Kind Field::TYPE_MESSAGE; +const Field_Kind Field::TYPE_BYTES; +const Field_Kind Field::TYPE_UINT32; +const Field_Kind Field::TYPE_ENUM; +const Field_Kind Field::TYPE_SFIXED32; +const Field_Kind Field::TYPE_SFIXED64; +const Field_Kind Field::TYPE_SINT32; +const Field_Kind Field::TYPE_SINT64; +const Field_Kind Field::Kind_MIN; +const Field_Kind Field::Kind_MAX; +const int Field::Kind_ARRAYSIZE; +#endif // _MSC_VER +const ::google::protobuf::EnumDescriptor* Field_Cardinality_descriptor() { + protobuf_AssignDescriptorsOnce(); + return Field_Cardinality_descriptor_; +} +bool Field_Cardinality_IsValid(int value) { + switch(value) { + case 0: + case 1: + case 2: + case 3: + return true; + default: + return false; + } +} + +#ifndef _MSC_VER +const Field_Cardinality Field::CARDINALITY_UNKNOWN; +const Field_Cardinality Field::CARDINALITY_OPTIONAL; +const Field_Cardinality Field::CARDINALITY_REQUIRED; +const Field_Cardinality Field::CARDINALITY_REPEATED; +const Field_Cardinality Field::Cardinality_MIN; +const Field_Cardinality Field::Cardinality_MAX; +const int Field::Cardinality_ARRAYSIZE; +#endif // _MSC_VER +#ifndef _MSC_VER +const int Field::kKindFieldNumber; +const int Field::kCardinalityFieldNumber; +const int Field::kNumberFieldNumber; +const int Field::kNameFieldNumber; +const int Field::kTypeUrlFieldNumber; +const int Field::kOneofIndexFieldNumber; +const int Field::kPackedFieldNumber; +const int Field::kOptionsFieldNumber; +#endif // !_MSC_VER + +Field::Field() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:google.protobuf.Field) +} + +void Field::InitAsDefaultInstance() { + _is_default_instance_ = true; +} + +Field::Field(const Field& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:google.protobuf.Field) +} + +void Field::SharedCtor() { + _is_default_instance_ = false; + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + kind_ = 0; + cardinality_ = 0; + number_ = 0; + name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + type_url_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + oneof_index_ = 0; + packed_ = false; +} + +Field::~Field() { + // @@protoc_insertion_point(destructor:google.protobuf.Field) + SharedDtor(); +} + +void Field::SharedDtor() { + name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + type_url_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (this != default_instance_) { + } +} + +void Field::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Field::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Field_descriptor_; +} + +const Field& Field::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto(); + return *default_instance_; +} + +Field* Field::default_instance_ = NULL; + +Field* Field::New(::google::protobuf::Arena* arena) const { + Field* n = new Field; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void Field::Clear() { +#define ZR_HELPER_(f) reinterpret_cast<char*>(\ + &reinterpret_cast<Field*>(16)->f) + +#define ZR_(first, last) do {\ + ::memset(&first, 0,\ + ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\ +} while (0) + + ZR_(kind_, cardinality_); + ZR_(number_, oneof_index_); + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + packed_ = false; + +#undef ZR_HELPER_ +#undef ZR_ + + options_.Clear(); +} + +bool Field::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:google.protobuf.Field) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional .google.protobuf.Field.Kind kind = 1; + case 1: { + if (tag == 8) { + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + set_kind(static_cast< ::google::protobuf::Field_Kind >(value)); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_cardinality; + break; + } + + // optional .google.protobuf.Field.Cardinality cardinality = 2; + case 2: { + if (tag == 16) { + parse_cardinality: + int value; + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( + input, &value))); + set_cardinality(static_cast< ::google::protobuf::Field_Cardinality >(value)); + } else { + goto handle_unusual; + } + if (input->ExpectTag(24)) goto parse_number; + break; + } + + // optional int32 number = 3; + case 3: { + if (tag == 24) { + parse_number: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &number_))); + + } else { + goto handle_unusual; + } + if (input->ExpectTag(34)) goto parse_name; + break; + } + + // optional string name = 4; + case 4: { + if (tag == 34) { + parse_name: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "google.protobuf.Field.name"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(50)) goto parse_type_url; + break; + } + + // optional string type_url = 6; + case 6: { + if (tag == 50) { + parse_type_url: + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_type_url())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->type_url().data(), this->type_url().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "google.protobuf.Field.type_url"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(56)) goto parse_oneof_index; + break; + } + + // optional int32 oneof_index = 7; + case 7: { + if (tag == 56) { + parse_oneof_index: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &oneof_index_))); + + } else { + goto handle_unusual; + } + if (input->ExpectTag(64)) goto parse_packed; + break; + } + + // optional bool packed = 8; + case 8: { + if (tag == 64) { + parse_packed: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &packed_))); + + } else { + goto handle_unusual; + } + if (input->ExpectTag(74)) goto parse_options; + break; + } + + // repeated .google.protobuf.Option options = 9; + case 9: { + if (tag == 74) { + parse_options: + DO_(input->IncrementRecursionDepth()); + parse_loop_options: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + input, add_options())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(74)) goto parse_loop_options; + input->UnsafeDecrementRecursionDepth(); + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:google.protobuf.Field) + return true; +failure: + // @@protoc_insertion_point(parse_failure:google.protobuf.Field) + return false; +#undef DO_ +} + +void Field::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:google.protobuf.Field) + // optional .google.protobuf.Field.Kind kind = 1; + if (this->kind() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 1, this->kind(), output); + } + + // optional .google.protobuf.Field.Cardinality cardinality = 2; + if (this->cardinality() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteEnum( + 2, this->cardinality(), output); + } + + // optional int32 number = 3; + if (this->number() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->number(), output); + } + + // optional string name = 4; + if (this->name().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.Field.name"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 4, this->name(), output); + } + + // optional string type_url = 6; + if (this->type_url().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->type_url().data(), this->type_url().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.Field.type_url"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 6, this->type_url(), output); + } + + // optional int32 oneof_index = 7; + if (this->oneof_index() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(7, this->oneof_index(), output); + } + + // optional bool packed = 8; + if (this->packed() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteBool(8, this->packed(), output); + } + + // repeated .google.protobuf.Option options = 9; + for (unsigned int i = 0, n = this->options_size(); i < n; i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 9, this->options(i), output); + } + + // @@protoc_insertion_point(serialize_end:google.protobuf.Field) +} + +::google::protobuf::uint8* Field::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Field) + // optional .google.protobuf.Field.Kind kind = 1; + if (this->kind() != 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 1, this->kind(), target); + } + + // optional .google.protobuf.Field.Cardinality cardinality = 2; + if (this->cardinality() != 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( + 2, this->cardinality(), target); + } + + // optional int32 number = 3; + if (this->number() != 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->number(), target); + } + + // optional string name = 4; + if (this->name().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.Field.name"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 4, this->name(), target); + } + + // optional string type_url = 6; + if (this->type_url().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->type_url().data(), this->type_url().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.Field.type_url"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 6, this->type_url(), target); + } + + // optional int32 oneof_index = 7; + if (this->oneof_index() != 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(7, this->oneof_index(), target); + } + + // optional bool packed = 8; + if (this->packed() != 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(8, this->packed(), target); + } + + // repeated .google.protobuf.Option options = 9; + for (unsigned int i = 0, n = this->options_size(); i < n; i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 9, this->options(i), target); + } + + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Field) + return target; +} + +int Field::ByteSize() const { + int total_size = 0; + + // optional .google.protobuf.Field.Kind kind = 1; + if (this->kind() != 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->kind()); + } + + // optional .google.protobuf.Field.Cardinality cardinality = 2; + if (this->cardinality() != 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->cardinality()); + } + + // optional int32 number = 3; + if (this->number() != 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->number()); + } + + // optional string name = 4; + if (this->name().size() > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + // optional string type_url = 6; + if (this->type_url().size() > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->type_url()); + } + + // optional int32 oneof_index = 7; + if (this->oneof_index() != 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->oneof_index()); + } + + // optional bool packed = 8; + if (this->packed() != 0) { + total_size += 1 + 1; + } + + // repeated .google.protobuf.Option options = 9; + total_size += 1 * this->options_size(); + for (int i = 0; i < this->options_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->options(i)); + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Field::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const Field* source = + ::google::protobuf::internal::DynamicCastToGenerated<const Field>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Field::MergeFrom(const Field& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + options_.MergeFrom(from.options_); + if (from.kind() != 0) { + set_kind(from.kind()); + } + if (from.cardinality() != 0) { + set_cardinality(from.cardinality()); + } + if (from.number() != 0) { + set_number(from.number()); + } + if (from.name().size() > 0) { + + name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); + } + if (from.type_url().size() > 0) { + + type_url_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.type_url_); + } + if (from.oneof_index() != 0) { + set_oneof_index(from.oneof_index()); + } + if (from.packed() != 0) { + set_packed(from.packed()); + } +} + +void Field::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Field::CopyFrom(const Field& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Field::IsInitialized() const { + + return true; +} + +void Field::Swap(Field* other) { + if (other == this) return; + InternalSwap(other); +} +void Field::InternalSwap(Field* other) { + std::swap(kind_, other->kind_); + std::swap(cardinality_, other->cardinality_); + std::swap(number_, other->number_); + name_.Swap(&other->name_); + type_url_.Swap(&other->type_url_); + std::swap(oneof_index_, other->oneof_index_); + std::swap(packed_, other->packed_); + options_.UnsafeArenaSwap(&other->options_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata Field::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Field_descriptor_; + metadata.reflection = Field_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// Field + +// optional .google.protobuf.Field.Kind kind = 1; +void Field::clear_kind() { + kind_ = 0; +} + ::google::protobuf::Field_Kind Field::kind() const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.kind) + return static_cast< ::google::protobuf::Field_Kind >(kind_); +} + void Field::set_kind(::google::protobuf::Field_Kind value) { + + kind_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Field.kind) +} + +// optional .google.protobuf.Field.Cardinality cardinality = 2; +void Field::clear_cardinality() { + cardinality_ = 0; +} + ::google::protobuf::Field_Cardinality Field::cardinality() const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.cardinality) + return static_cast< ::google::protobuf::Field_Cardinality >(cardinality_); +} + void Field::set_cardinality(::google::protobuf::Field_Cardinality value) { + + cardinality_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Field.cardinality) +} + +// optional int32 number = 3; +void Field::clear_number() { + number_ = 0; +} + ::google::protobuf::int32 Field::number() const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.number) + return number_; +} + void Field::set_number(::google::protobuf::int32 value) { + + number_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Field.number) +} + +// optional string name = 4; +void Field::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + const ::std::string& Field::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void Field::set_name(const ::std::string& value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Field.name) +} + void Field::set_name(const char* value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Field.name) +} + void Field::set_name(const char* value, size_t size) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Field.name) +} + ::std::string* Field::mutable_name() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Field.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* Field::release_name() { + + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void Field::set_allocated_name(::std::string* name) { + if (name != NULL) { + + } else { + + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.name) +} + +// optional string type_url = 6; +void Field::clear_type_url() { + type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + const ::std::string& Field::type_url() const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.type_url) + return type_url_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void Field::set_type_url(const ::std::string& value) { + + type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Field.type_url) +} + void Field::set_type_url(const char* value) { + + type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Field.type_url) +} + void Field::set_type_url(const char* value, size_t size) { + + type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Field.type_url) +} + ::std::string* Field::mutable_type_url() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Field.type_url) + return type_url_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* Field::release_type_url() { + + return type_url_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void Field::set_allocated_type_url(::std::string* type_url) { + if (type_url != NULL) { + + } else { + + } + type_url_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), type_url); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.type_url) +} + +// optional int32 oneof_index = 7; +void Field::clear_oneof_index() { + oneof_index_ = 0; +} + ::google::protobuf::int32 Field::oneof_index() const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.oneof_index) + return oneof_index_; +} + void Field::set_oneof_index(::google::protobuf::int32 value) { + + oneof_index_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Field.oneof_index) +} + +// optional bool packed = 8; +void Field::clear_packed() { + packed_ = false; +} + bool Field::packed() const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.packed) + return packed_; +} + void Field::set_packed(bool value) { + + packed_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Field.packed) +} + +// repeated .google.protobuf.Option options = 9; +int Field::options_size() const { + return options_.size(); +} +void Field::clear_options() { + options_.Clear(); +} + const ::google::protobuf::Option& Field::options(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.options) + return options_.Get(index); +} + ::google::protobuf::Option* Field::mutable_options(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Field.options) + return options_.Mutable(index); +} + ::google::protobuf::Option* Field::add_options() { + // @@protoc_insertion_point(field_add:google.protobuf.Field.options) + return options_.Add(); +} + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >& +Field::options() const { + // @@protoc_insertion_point(field_list:google.protobuf.Field.options) + return options_; +} + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >* +Field::mutable_options() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Field.options) + return &options_; +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// =================================================================== + +#ifndef _MSC_VER +const int Enum::kNameFieldNumber; +const int Enum::kEnumvalueFieldNumber; +const int Enum::kOptionsFieldNumber; +const int Enum::kSourceContextFieldNumber; +#endif // !_MSC_VER + +Enum::Enum() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:google.protobuf.Enum) +} + +void Enum::InitAsDefaultInstance() { + _is_default_instance_ = true; + source_context_ = const_cast< ::google::protobuf::SourceContext*>(&::google::protobuf::SourceContext::default_instance()); +} + +Enum::Enum(const Enum& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:google.protobuf.Enum) +} + +void Enum::SharedCtor() { + _is_default_instance_ = false; + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + source_context_ = NULL; +} + +Enum::~Enum() { + // @@protoc_insertion_point(destructor:google.protobuf.Enum) + SharedDtor(); +} + +void Enum::SharedDtor() { + name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (this != default_instance_) { + delete source_context_; + } +} + +void Enum::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Enum::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Enum_descriptor_; +} + +const Enum& Enum::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto(); + return *default_instance_; +} + +Enum* Enum::default_instance_ = NULL; + +Enum* Enum::New(::google::protobuf::Arena* arena) const { + Enum* n = new Enum; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void Enum::Clear() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (GetArenaNoVirtual() == NULL && source_context_ != NULL) delete source_context_; + source_context_ = NULL; + enumvalue_.Clear(); + options_.Clear(); +} + +bool Enum::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:google.protobuf.Enum) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string name = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "google.protobuf.Enum.name"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_enumvalue; + break; + } + + // repeated .google.protobuf.EnumValue enumvalue = 2; + case 2: { + if (tag == 18) { + parse_enumvalue: + DO_(input->IncrementRecursionDepth()); + parse_loop_enumvalue: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + input, add_enumvalue())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_loop_enumvalue; + if (input->ExpectTag(26)) goto parse_loop_options; + input->UnsafeDecrementRecursionDepth(); + break; + } + + // repeated .google.protobuf.Option options = 3; + case 3: { + if (tag == 26) { + DO_(input->IncrementRecursionDepth()); + parse_loop_options: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + input, add_options())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(26)) goto parse_loop_options; + input->UnsafeDecrementRecursionDepth(); + if (input->ExpectTag(34)) goto parse_source_context; + break; + } + + // optional .google.protobuf.SourceContext source_context = 4; + case 4: { + if (tag == 34) { + parse_source_context: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_source_context())); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:google.protobuf.Enum) + return true; +failure: + // @@protoc_insertion_point(parse_failure:google.protobuf.Enum) + return false; +#undef DO_ +} + +void Enum::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:google.protobuf.Enum) + // optional string name = 1; + if (this->name().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.Enum.name"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->name(), output); + } + + // repeated .google.protobuf.EnumValue enumvalue = 2; + for (unsigned int i = 0, n = this->enumvalue_size(); i < n; i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, this->enumvalue(i), output); + } + + // repeated .google.protobuf.Option options = 3; + for (unsigned int i = 0, n = this->options_size(); i < n; i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 3, this->options(i), output); + } + + // optional .google.protobuf.SourceContext source_context = 4; + if (this->has_source_context()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 4, *this->source_context_, output); + } + + // @@protoc_insertion_point(serialize_end:google.protobuf.Enum) +} + +::google::protobuf::uint8* Enum::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Enum) + // optional string name = 1; + if (this->name().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.Enum.name"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); + } + + // repeated .google.protobuf.EnumValue enumvalue = 2; + for (unsigned int i = 0, n = this->enumvalue_size(); i < n; i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, this->enumvalue(i), target); + } + + // repeated .google.protobuf.Option options = 3; + for (unsigned int i = 0, n = this->options_size(); i < n; i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 3, this->options(i), target); + } + + // optional .google.protobuf.SourceContext source_context = 4; + if (this->has_source_context()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 4, *this->source_context_, target); + } + + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Enum) + return target; +} + +int Enum::ByteSize() const { + int total_size = 0; + + // optional string name = 1; + if (this->name().size() > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + // optional .google.protobuf.SourceContext source_context = 4; + if (this->has_source_context()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + *this->source_context_); + } + + // repeated .google.protobuf.EnumValue enumvalue = 2; + total_size += 1 * this->enumvalue_size(); + for (int i = 0; i < this->enumvalue_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->enumvalue(i)); + } + + // repeated .google.protobuf.Option options = 3; + total_size += 1 * this->options_size(); + for (int i = 0; i < this->options_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->options(i)); + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Enum::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const Enum* source = + ::google::protobuf::internal::DynamicCastToGenerated<const Enum>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Enum::MergeFrom(const Enum& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + enumvalue_.MergeFrom(from.enumvalue_); + options_.MergeFrom(from.options_); + if (from.name().size() > 0) { + + name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); + } + if (from.has_source_context()) { + mutable_source_context()->::google::protobuf::SourceContext::MergeFrom(from.source_context()); + } +} + +void Enum::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Enum::CopyFrom(const Enum& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Enum::IsInitialized() const { + + return true; +} + +void Enum::Swap(Enum* other) { + if (other == this) return; + InternalSwap(other); +} +void Enum::InternalSwap(Enum* other) { + name_.Swap(&other->name_); + enumvalue_.UnsafeArenaSwap(&other->enumvalue_); + options_.UnsafeArenaSwap(&other->options_); + std::swap(source_context_, other->source_context_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata Enum::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Enum_descriptor_; + metadata.reflection = Enum_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// Enum + +// optional string name = 1; +void Enum::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + const ::std::string& Enum::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.Enum.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void Enum::set_name(const ::std::string& value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Enum.name) +} + void Enum::set_name(const char* value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Enum.name) +} + void Enum::set_name(const char* value, size_t size) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Enum.name) +} + ::std::string* Enum::mutable_name() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* Enum::release_name() { + + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void Enum::set_allocated_name(::std::string* name) { + if (name != NULL) { + + } else { + + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Enum.name) +} + +// repeated .google.protobuf.EnumValue enumvalue = 2; +int Enum::enumvalue_size() const { + return enumvalue_.size(); +} +void Enum::clear_enumvalue() { + enumvalue_.Clear(); +} + const ::google::protobuf::EnumValue& Enum::enumvalue(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Enum.enumvalue) + return enumvalue_.Get(index); +} + ::google::protobuf::EnumValue* Enum::mutable_enumvalue(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.enumvalue) + return enumvalue_.Mutable(index); +} + ::google::protobuf::EnumValue* Enum::add_enumvalue() { + // @@protoc_insertion_point(field_add:google.protobuf.Enum.enumvalue) + return enumvalue_.Add(); +} + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValue >& +Enum::enumvalue() const { + // @@protoc_insertion_point(field_list:google.protobuf.Enum.enumvalue) + return enumvalue_; +} + ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValue >* +Enum::mutable_enumvalue() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Enum.enumvalue) + return &enumvalue_; +} + +// repeated .google.protobuf.Option options = 3; +int Enum::options_size() const { + return options_.size(); +} +void Enum::clear_options() { + options_.Clear(); +} + const ::google::protobuf::Option& Enum::options(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Enum.options) + return options_.Get(index); +} + ::google::protobuf::Option* Enum::mutable_options(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.options) + return options_.Mutable(index); +} + ::google::protobuf::Option* Enum::add_options() { + // @@protoc_insertion_point(field_add:google.protobuf.Enum.options) + return options_.Add(); +} + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >& +Enum::options() const { + // @@protoc_insertion_point(field_list:google.protobuf.Enum.options) + return options_; +} + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >* +Enum::mutable_options() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Enum.options) + return &options_; +} + +// optional .google.protobuf.SourceContext source_context = 4; +bool Enum::has_source_context() const { + return !_is_default_instance_ && source_context_ != NULL; +} +void Enum::clear_source_context() { + if (GetArenaNoVirtual() == NULL && source_context_ != NULL) delete source_context_; + source_context_ = NULL; +} + const ::google::protobuf::SourceContext& Enum::source_context() const { + // @@protoc_insertion_point(field_get:google.protobuf.Enum.source_context) + return source_context_ != NULL ? *source_context_ : *default_instance_->source_context_; +} + ::google::protobuf::SourceContext* Enum::mutable_source_context() { + + if (source_context_ == NULL) { + source_context_ = new ::google::protobuf::SourceContext; + } + // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.source_context) + return source_context_; +} + ::google::protobuf::SourceContext* Enum::release_source_context() { + + ::google::protobuf::SourceContext* temp = source_context_; + source_context_ = NULL; + return temp; +} + void Enum::set_allocated_source_context(::google::protobuf::SourceContext* source_context) { + delete source_context_; + source_context_ = source_context; + if (source_context) { + + } else { + + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Enum.source_context) +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// =================================================================== + +#ifndef _MSC_VER +const int EnumValue::kNameFieldNumber; +const int EnumValue::kNumberFieldNumber; +const int EnumValue::kOptionsFieldNumber; +#endif // !_MSC_VER + +EnumValue::EnumValue() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:google.protobuf.EnumValue) +} + +void EnumValue::InitAsDefaultInstance() { + _is_default_instance_ = true; +} + +EnumValue::EnumValue(const EnumValue& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:google.protobuf.EnumValue) +} + +void EnumValue::SharedCtor() { + _is_default_instance_ = false; + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + number_ = 0; +} + +EnumValue::~EnumValue() { + // @@protoc_insertion_point(destructor:google.protobuf.EnumValue) + SharedDtor(); +} + +void EnumValue::SharedDtor() { + name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (this != default_instance_) { + } +} + +void EnumValue::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* EnumValue::descriptor() { + protobuf_AssignDescriptorsOnce(); + return EnumValue_descriptor_; +} + +const EnumValue& EnumValue::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto(); + return *default_instance_; +} + +EnumValue* EnumValue::default_instance_ = NULL; + +EnumValue* EnumValue::New(::google::protobuf::Arena* arena) const { + EnumValue* n = new EnumValue; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void EnumValue::Clear() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + number_ = 0; + options_.Clear(); +} + +bool EnumValue::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:google.protobuf.EnumValue) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string name = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "google.protobuf.EnumValue.name"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(16)) goto parse_number; + break; + } + + // optional int32 number = 2; + case 2: { + if (tag == 16) { + parse_number: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &number_))); + + } else { + goto handle_unusual; + } + if (input->ExpectTag(26)) goto parse_options; + break; + } + + // repeated .google.protobuf.Option options = 3; + case 3: { + if (tag == 26) { + parse_options: + DO_(input->IncrementRecursionDepth()); + parse_loop_options: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + input, add_options())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(26)) goto parse_loop_options; + input->UnsafeDecrementRecursionDepth(); + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:google.protobuf.EnumValue) + return true; +failure: + // @@protoc_insertion_point(parse_failure:google.protobuf.EnumValue) + return false; +#undef DO_ +} + +void EnumValue::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:google.protobuf.EnumValue) + // optional string name = 1; + if (this->name().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.EnumValue.name"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->name(), output); + } + + // optional int32 number = 2; + if (this->number() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->number(), output); + } + + // repeated .google.protobuf.Option options = 3; + for (unsigned int i = 0, n = this->options_size(); i < n; i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 3, this->options(i), output); + } + + // @@protoc_insertion_point(serialize_end:google.protobuf.EnumValue) +} + +::google::protobuf::uint8* EnumValue::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumValue) + // optional string name = 1; + if (this->name().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.EnumValue.name"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); + } + + // optional int32 number = 2; + if (this->number() != 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->number(), target); + } + + // repeated .google.protobuf.Option options = 3; + for (unsigned int i = 0, n = this->options_size(); i < n; i++) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 3, this->options(i), target); + } + + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumValue) + return target; +} + +int EnumValue::ByteSize() const { + int total_size = 0; + + // optional string name = 1; + if (this->name().size() > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + // optional int32 number = 2; + if (this->number() != 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->number()); + } + + // repeated .google.protobuf.Option options = 3; + total_size += 1 * this->options_size(); + for (int i = 0; i < this->options_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->options(i)); + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void EnumValue::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const EnumValue* source = + ::google::protobuf::internal::DynamicCastToGenerated<const EnumValue>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void EnumValue::MergeFrom(const EnumValue& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + options_.MergeFrom(from.options_); + if (from.name().size() > 0) { + + name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); + } + if (from.number() != 0) { + set_number(from.number()); + } +} + +void EnumValue::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void EnumValue::CopyFrom(const EnumValue& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool EnumValue::IsInitialized() const { + + return true; +} + +void EnumValue::Swap(EnumValue* other) { + if (other == this) return; + InternalSwap(other); +} +void EnumValue::InternalSwap(EnumValue* other) { + name_.Swap(&other->name_); + std::swap(number_, other->number_); + options_.UnsafeArenaSwap(&other->options_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata EnumValue::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = EnumValue_descriptor_; + metadata.reflection = EnumValue_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// EnumValue + +// optional string name = 1; +void EnumValue::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + const ::std::string& EnumValue::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumValue.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void EnumValue::set_name(const ::std::string& value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.EnumValue.name) +} + void EnumValue::set_name(const char* value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.EnumValue.name) +} + void EnumValue::set_name(const char* value, size_t size) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.EnumValue.name) +} + ::std::string* EnumValue::mutable_name() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValue.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* EnumValue::release_name() { + + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void EnumValue::set_allocated_name(::std::string* name) { + if (name != NULL) { + + } else { + + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumValue.name) +} + +// optional int32 number = 2; +void EnumValue::clear_number() { + number_ = 0; +} + ::google::protobuf::int32 EnumValue::number() const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumValue.number) + return number_; +} + void EnumValue::set_number(::google::protobuf::int32 value) { + + number_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.EnumValue.number) +} + +// repeated .google.protobuf.Option options = 3; +int EnumValue::options_size() const { + return options_.size(); +} +void EnumValue::clear_options() { + options_.Clear(); +} + const ::google::protobuf::Option& EnumValue::options(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumValue.options) + return options_.Get(index); +} + ::google::protobuf::Option* EnumValue::mutable_options(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValue.options) + return options_.Mutable(index); +} + ::google::protobuf::Option* EnumValue::add_options() { + // @@protoc_insertion_point(field_add:google.protobuf.EnumValue.options) + return options_.Add(); +} + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >& +EnumValue::options() const { + // @@protoc_insertion_point(field_list:google.protobuf.EnumValue.options) + return options_; +} + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >* +EnumValue::mutable_options() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumValue.options) + return &options_; +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// =================================================================== + +#ifndef _MSC_VER +const int Option::kNameFieldNumber; +const int Option::kValueFieldNumber; +#endif // !_MSC_VER + +Option::Option() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:google.protobuf.Option) +} + +void Option::InitAsDefaultInstance() { + _is_default_instance_ = true; + value_ = const_cast< ::google::protobuf::Any*>(&::google::protobuf::Any::default_instance()); +} + +Option::Option(const Option& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:google.protobuf.Option) +} + +void Option::SharedCtor() { + _is_default_instance_ = false; + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + value_ = NULL; +} + +Option::~Option() { + // @@protoc_insertion_point(destructor:google.protobuf.Option) + SharedDtor(); +} + +void Option::SharedDtor() { + name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (this != default_instance_) { + delete value_; + } +} + +void Option::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Option::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Option_descriptor_; +} + +const Option& Option::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto(); + return *default_instance_; +} + +Option* Option::default_instance_ = NULL; + +Option* Option::New(::google::protobuf::Arena* arena) const { + Option* n = new Option; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void Option::Clear() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (GetArenaNoVirtual() == NULL && value_ != NULL) delete value_; + value_ = NULL; +} + +bool Option::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:google.protobuf.Option) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string name = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "google.protobuf.Option.name"); + } else { + goto handle_unusual; + } + if (input->ExpectTag(18)) goto parse_value; + break; + } + + // optional .google.protobuf.Any value = 2; + case 2: { + if (tag == 18) { + parse_value: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_value())); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:google.protobuf.Option) + return true; +failure: + // @@protoc_insertion_point(parse_failure:google.protobuf.Option) + return false; +#undef DO_ +} + +void Option::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:google.protobuf.Option) + // optional string name = 1; + if (this->name().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.Option.name"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->name(), output); + } + + // optional .google.protobuf.Any value = 2; + if (this->has_value()) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 2, *this->value_, output); + } + + // @@protoc_insertion_point(serialize_end:google.protobuf.Option) +} + +::google::protobuf::uint8* Option::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Option) + // optional string name = 1; + if (this->name().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.Option.name"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); + } + + // optional .google.protobuf.Any value = 2; + if (this->has_value()) { + target = ::google::protobuf::internal::WireFormatLite:: + WriteMessageNoVirtualToArray( + 2, *this->value_, target); + } + + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Option) + return target; +} + +int Option::ByteSize() const { + int total_size = 0; + + // optional string name = 1; + if (this->name().size() > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + // optional .google.protobuf.Any value = 2; + if (this->has_value()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + *this->value_); + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Option::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const Option* source = + ::google::protobuf::internal::DynamicCastToGenerated<const Option>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Option::MergeFrom(const Option& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from.name().size() > 0) { + + name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); + } + if (from.has_value()) { + mutable_value()->::google::protobuf::Any::MergeFrom(from.value()); + } +} + +void Option::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Option::CopyFrom(const Option& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Option::IsInitialized() const { + + return true; +} + +void Option::Swap(Option* other) { + if (other == this) return; + InternalSwap(other); +} +void Option::InternalSwap(Option* other) { + name_.Swap(&other->name_); + std::swap(value_, other->value_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata Option::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Option_descriptor_; + metadata.reflection = Option_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// Option + +// optional string name = 1; +void Option::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + const ::std::string& Option::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.Option.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void Option::set_name(const ::std::string& value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Option.name) +} + void Option::set_name(const char* value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Option.name) +} + void Option::set_name(const char* value, size_t size) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Option.name) +} + ::std::string* Option::mutable_name() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Option.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* Option::release_name() { + + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void Option::set_allocated_name(::std::string* name) { + if (name != NULL) { + + } else { + + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Option.name) +} + +// optional .google.protobuf.Any value = 2; +bool Option::has_value() const { + return !_is_default_instance_ && value_ != NULL; +} +void Option::clear_value() { + if (GetArenaNoVirtual() == NULL && value_ != NULL) delete value_; + value_ = NULL; +} + const ::google::protobuf::Any& Option::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Option.value) + return value_ != NULL ? *value_ : *default_instance_->value_; +} + ::google::protobuf::Any* Option::mutable_value() { + + if (value_ == NULL) { + value_ = new ::google::protobuf::Any; + } + // @@protoc_insertion_point(field_mutable:google.protobuf.Option.value) + return value_; +} + ::google::protobuf::Any* Option::release_value() { + + ::google::protobuf::Any* temp = value_; + value_ = NULL; + return temp; +} + void Option::set_allocated_value(::google::protobuf::Any* value) { + delete value_; + value_ = value; + if (value) { + + } else { + + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Option.value) +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// @@protoc_insertion_point(namespace_scope) + +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) diff --git a/src/google/protobuf/type.pb.h b/src/google/protobuf/type.pb.h new file mode 100644 index 00000000..c9952efa --- /dev/null +++ b/src/google/protobuf/type.pb.h @@ -0,0 +1,1516 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/type.proto + +#ifndef PROTOBUF_google_2fprotobuf_2ftype_2eproto__INCLUDED +#define PROTOBUF_google_2fprotobuf_2ftype_2eproto__INCLUDED + +#include <string> + +#include <google/protobuf/stubs/common.h> + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#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 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include <google/protobuf/arena.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/metadata.h> +#include <google/protobuf/message.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/generated_enum_reflection.h> +#include <google/protobuf/unknown_field_set.h> +#include "google/protobuf/any.pb.h" +#include "google/protobuf/source_context.pb.h" +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { + +// Internal implementation detail -- do not call these. +void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto(); +void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto(); +void protobuf_ShutdownFile_google_2fprotobuf_2ftype_2eproto(); + +class Type; +class Field; +class Enum; +class EnumValue; +class Option; + +enum Field_Kind { + 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_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_ = ::google::protobuf::kint32min, + Field_Kind_Field_Kind_INT_MAX_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32max +}; +LIBPROTOBUF_EXPORT bool Field_Kind_IsValid(int value); +const Field_Kind Field_Kind_Kind_MIN = Field_Kind_TYPE_UNKNOWN; +const Field_Kind Field_Kind_Kind_MAX = Field_Kind_TYPE_SINT64; +const int Field_Kind_Kind_ARRAYSIZE = Field_Kind_Kind_MAX + 1; + +LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* Field_Kind_descriptor(); +inline const ::std::string& Field_Kind_Name(Field_Kind value) { + return ::google::protobuf::internal::NameOfEnum( + Field_Kind_descriptor(), value); +} +inline bool Field_Kind_Parse( + const ::std::string& name, Field_Kind* value) { + return ::google::protobuf::internal::ParseNamedEnum<Field_Kind>( + Field_Kind_descriptor(), name, value); +} +enum Field_Cardinality { + 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_ = ::google::protobuf::kint32min, + Field_Cardinality_Field_Cardinality_INT_MAX_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32max +}; +LIBPROTOBUF_EXPORT bool Field_Cardinality_IsValid(int value); +const Field_Cardinality Field_Cardinality_Cardinality_MIN = Field_Cardinality_CARDINALITY_UNKNOWN; +const Field_Cardinality Field_Cardinality_Cardinality_MAX = Field_Cardinality_CARDINALITY_REPEATED; +const int Field_Cardinality_Cardinality_ARRAYSIZE = Field_Cardinality_Cardinality_MAX + 1; + +LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* Field_Cardinality_descriptor(); +inline const ::std::string& Field_Cardinality_Name(Field_Cardinality value) { + return ::google::protobuf::internal::NameOfEnum( + Field_Cardinality_descriptor(), value); +} +inline bool Field_Cardinality_Parse( + const ::std::string& name, Field_Cardinality* value) { + return ::google::protobuf::internal::ParseNamedEnum<Field_Cardinality>( + Field_Cardinality_descriptor(), name, value); +} +// =================================================================== + +class LIBPROTOBUF_EXPORT Type : public ::google::protobuf::Message { + public: + Type(); + virtual ~Type(); + + Type(const Type& from); + + inline Type& operator=(const Type& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Type& default_instance(); + + void Swap(Type* other); + + // implements Message ---------------------------------------------- + + inline Type* New() const { return New(NULL); } + + Type* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Type& from); + void MergeFrom(const Type& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Type* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string name = 1; + void clear_name(); + static const int kNameFieldNumber = 1; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // repeated .google.protobuf.Field fields = 2; + int fields_size() const; + void clear_fields(); + static const int kFieldsFieldNumber = 2; + const ::google::protobuf::Field& fields(int index) const; + ::google::protobuf::Field* mutable_fields(int index); + ::google::protobuf::Field* add_fields(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Field >& + fields() const; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Field >* + mutable_fields(); + + // repeated string oneofs = 3; + int oneofs_size() const; + void clear_oneofs(); + static const int kOneofsFieldNumber = 3; + 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, 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(const char* value); + void add_oneofs(const char* value, size_t size); + const ::google::protobuf::RepeatedPtrField< ::std::string>& oneofs() const; + ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_oneofs(); + + // repeated .google.protobuf.Option options = 4; + int options_size() const; + void clear_options(); + static const int kOptionsFieldNumber = 4; + const ::google::protobuf::Option& options(int index) const; + ::google::protobuf::Option* mutable_options(int index); + ::google::protobuf::Option* add_options(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >& + options() const; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >* + mutable_options(); + + // optional .google.protobuf.SourceContext source_context = 5; + bool has_source_context() const; + void clear_source_context(); + static const int kSourceContextFieldNumber = 5; + const ::google::protobuf::SourceContext& source_context() const; + ::google::protobuf::SourceContext* mutable_source_context(); + ::google::protobuf::SourceContext* release_source_context(); + void set_allocated_source_context(::google::protobuf::SourceContext* source_context); + + // @@protoc_insertion_point(class_scope:google.protobuf.Type) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Field > fields_; + ::google::protobuf::RepeatedPtrField< ::std::string> oneofs_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_; + ::google::protobuf::SourceContext* source_context_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2ftype_2eproto(); + + void InitAsDefaultInstance(); + static Type* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT Field : public ::google::protobuf::Message { + public: + Field(); + virtual ~Field(); + + Field(const Field& from); + + inline Field& operator=(const Field& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Field& default_instance(); + + void Swap(Field* other); + + // implements Message ---------------------------------------------- + + inline Field* New() const { return New(NULL); } + + Field* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Field& from); + void MergeFrom(const Field& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Field* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + typedef Field_Kind Kind; + static const Kind TYPE_UNKNOWN = Field_Kind_TYPE_UNKNOWN; + static const Kind TYPE_DOUBLE = Field_Kind_TYPE_DOUBLE; + static const Kind TYPE_FLOAT = Field_Kind_TYPE_FLOAT; + static const Kind TYPE_INT64 = Field_Kind_TYPE_INT64; + static const Kind TYPE_UINT64 = Field_Kind_TYPE_UINT64; + static const Kind TYPE_INT32 = Field_Kind_TYPE_INT32; + static const Kind TYPE_FIXED64 = Field_Kind_TYPE_FIXED64; + static const Kind TYPE_FIXED32 = Field_Kind_TYPE_FIXED32; + static const Kind TYPE_BOOL = Field_Kind_TYPE_BOOL; + static const Kind TYPE_STRING = Field_Kind_TYPE_STRING; + static const Kind TYPE_MESSAGE = Field_Kind_TYPE_MESSAGE; + static const Kind TYPE_BYTES = Field_Kind_TYPE_BYTES; + static const Kind TYPE_UINT32 = Field_Kind_TYPE_UINT32; + static const Kind TYPE_ENUM = Field_Kind_TYPE_ENUM; + static const Kind TYPE_SFIXED32 = Field_Kind_TYPE_SFIXED32; + static const Kind TYPE_SFIXED64 = Field_Kind_TYPE_SFIXED64; + static const Kind TYPE_SINT32 = Field_Kind_TYPE_SINT32; + static const Kind TYPE_SINT64 = Field_Kind_TYPE_SINT64; + static inline bool Kind_IsValid(int value) { + return Field_Kind_IsValid(value); + } + static const Kind Kind_MIN = + Field_Kind_Kind_MIN; + static const Kind Kind_MAX = + Field_Kind_Kind_MAX; + static const int Kind_ARRAYSIZE = + Field_Kind_Kind_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + Kind_descriptor() { + return Field_Kind_descriptor(); + } + static inline const ::std::string& Kind_Name(Kind value) { + return Field_Kind_Name(value); + } + static inline bool Kind_Parse(const ::std::string& name, + Kind* value) { + return Field_Kind_Parse(name, value); + } + + typedef Field_Cardinality Cardinality; + static const Cardinality CARDINALITY_UNKNOWN = Field_Cardinality_CARDINALITY_UNKNOWN; + static const Cardinality CARDINALITY_OPTIONAL = Field_Cardinality_CARDINALITY_OPTIONAL; + static const Cardinality CARDINALITY_REQUIRED = Field_Cardinality_CARDINALITY_REQUIRED; + static const Cardinality CARDINALITY_REPEATED = Field_Cardinality_CARDINALITY_REPEATED; + static inline bool Cardinality_IsValid(int value) { + return Field_Cardinality_IsValid(value); + } + static const Cardinality Cardinality_MIN = + Field_Cardinality_Cardinality_MIN; + static const Cardinality Cardinality_MAX = + Field_Cardinality_Cardinality_MAX; + static const int Cardinality_ARRAYSIZE = + Field_Cardinality_Cardinality_ARRAYSIZE; + static inline const ::google::protobuf::EnumDescriptor* + Cardinality_descriptor() { + return Field_Cardinality_descriptor(); + } + static inline const ::std::string& Cardinality_Name(Cardinality value) { + return Field_Cardinality_Name(value); + } + static inline bool Cardinality_Parse(const ::std::string& name, + Cardinality* value) { + return Field_Cardinality_Parse(name, value); + } + + // accessors ------------------------------------------------------- + + // optional .google.protobuf.Field.Kind kind = 1; + void clear_kind(); + static const int kKindFieldNumber = 1; + ::google::protobuf::Field_Kind kind() const; + void set_kind(::google::protobuf::Field_Kind value); + + // optional .google.protobuf.Field.Cardinality cardinality = 2; + void clear_cardinality(); + static const int kCardinalityFieldNumber = 2; + ::google::protobuf::Field_Cardinality cardinality() const; + void set_cardinality(::google::protobuf::Field_Cardinality value); + + // optional int32 number = 3; + void clear_number(); + static const int kNumberFieldNumber = 3; + ::google::protobuf::int32 number() const; + void set_number(::google::protobuf::int32 value); + + // optional string name = 4; + void clear_name(); + static const int kNameFieldNumber = 4; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // optional string type_url = 6; + void clear_type_url(); + static const int kTypeUrlFieldNumber = 6; + const ::std::string& type_url() const; + void set_type_url(const ::std::string& value); + void set_type_url(const char* value); + void set_type_url(const char* value, size_t size); + ::std::string* mutable_type_url(); + ::std::string* release_type_url(); + void set_allocated_type_url(::std::string* type_url); + + // optional int32 oneof_index = 7; + void clear_oneof_index(); + static const int kOneofIndexFieldNumber = 7; + ::google::protobuf::int32 oneof_index() const; + void set_oneof_index(::google::protobuf::int32 value); + + // optional bool packed = 8; + void clear_packed(); + static const int kPackedFieldNumber = 8; + bool packed() const; + void set_packed(bool value); + + // repeated .google.protobuf.Option options = 9; + int options_size() const; + void clear_options(); + static const int kOptionsFieldNumber = 9; + const ::google::protobuf::Option& options(int index) const; + ::google::protobuf::Option* mutable_options(int index); + ::google::protobuf::Option* add_options(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >& + options() const; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >* + mutable_options(); + + // @@protoc_insertion_point(class_scope:google.protobuf.Field) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + int kind_; + int cardinality_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::int32 number_; + ::google::protobuf::int32 oneof_index_; + ::google::protobuf::internal::ArenaStringPtr type_url_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_; + bool packed_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2ftype_2eproto(); + + void InitAsDefaultInstance(); + static Field* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT Enum : public ::google::protobuf::Message { + public: + Enum(); + virtual ~Enum(); + + Enum(const Enum& from); + + inline Enum& operator=(const Enum& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Enum& default_instance(); + + void Swap(Enum* other); + + // implements Message ---------------------------------------------- + + inline Enum* New() const { return New(NULL); } + + Enum* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Enum& from); + void MergeFrom(const Enum& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Enum* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string name = 1; + void clear_name(); + static const int kNameFieldNumber = 1; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // repeated .google.protobuf.EnumValue enumvalue = 2; + int enumvalue_size() const; + void clear_enumvalue(); + static const int kEnumvalueFieldNumber = 2; + const ::google::protobuf::EnumValue& enumvalue(int index) const; + ::google::protobuf::EnumValue* mutable_enumvalue(int index); + ::google::protobuf::EnumValue* add_enumvalue(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValue >& + enumvalue() const; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValue >* + mutable_enumvalue(); + + // repeated .google.protobuf.Option options = 3; + int options_size() const; + void clear_options(); + static const int kOptionsFieldNumber = 3; + const ::google::protobuf::Option& options(int index) const; + ::google::protobuf::Option* mutable_options(int index); + ::google::protobuf::Option* add_options(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >& + options() const; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >* + mutable_options(); + + // optional .google.protobuf.SourceContext source_context = 4; + bool has_source_context() const; + void clear_source_context(); + static const int kSourceContextFieldNumber = 4; + const ::google::protobuf::SourceContext& source_context() const; + ::google::protobuf::SourceContext* mutable_source_context(); + ::google::protobuf::SourceContext* release_source_context(); + void set_allocated_source_context(::google::protobuf::SourceContext* source_context); + + // @@protoc_insertion_point(class_scope:google.protobuf.Enum) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValue > enumvalue_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_; + ::google::protobuf::SourceContext* source_context_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2ftype_2eproto(); + + void InitAsDefaultInstance(); + static Enum* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT EnumValue : public ::google::protobuf::Message { + public: + EnumValue(); + virtual ~EnumValue(); + + EnumValue(const EnumValue& from); + + inline EnumValue& operator=(const EnumValue& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const EnumValue& default_instance(); + + void Swap(EnumValue* other); + + // implements Message ---------------------------------------------- + + inline EnumValue* New() const { return New(NULL); } + + EnumValue* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const EnumValue& from); + void MergeFrom(const EnumValue& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(EnumValue* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string name = 1; + void clear_name(); + static const int kNameFieldNumber = 1; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // optional int32 number = 2; + void clear_number(); + static const int kNumberFieldNumber = 2; + ::google::protobuf::int32 number() const; + void set_number(::google::protobuf::int32 value); + + // repeated .google.protobuf.Option options = 3; + int options_size() const; + void clear_options(); + static const int kOptionsFieldNumber = 3; + const ::google::protobuf::Option& options(int index) const; + ::google::protobuf::Option* mutable_options(int index); + ::google::protobuf::Option* add_options(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >& + options() const; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >* + mutable_options(); + + // @@protoc_insertion_point(class_scope:google.protobuf.EnumValue) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_; + ::google::protobuf::int32 number_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2ftype_2eproto(); + + void InitAsDefaultInstance(); + static EnumValue* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT Option : public ::google::protobuf::Message { + public: + Option(); + virtual ~Option(); + + Option(const Option& from); + + inline Option& operator=(const Option& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Option& default_instance(); + + void Swap(Option* other); + + // implements Message ---------------------------------------------- + + inline Option* New() const { return New(NULL); } + + Option* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Option& from); + void MergeFrom(const Option& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Option* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string name = 1; + void clear_name(); + static const int kNameFieldNumber = 1; + const ::std::string& name() const; + void set_name(const ::std::string& value); + void set_name(const char* value); + void set_name(const char* value, size_t size); + ::std::string* mutable_name(); + ::std::string* release_name(); + void set_allocated_name(::std::string* name); + + // optional .google.protobuf.Any value = 2; + bool has_value() const; + void clear_value(); + static const int kValueFieldNumber = 2; + const ::google::protobuf::Any& value() const; + ::google::protobuf::Any* mutable_value(); + ::google::protobuf::Any* release_value(); + void set_allocated_value(::google::protobuf::Any* value); + + // @@protoc_insertion_point(class_scope:google.protobuf.Option) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::Any* value_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2ftype_2eproto(); + + void InitAsDefaultInstance(); + static Option* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// Type + +// optional string name = 1; +inline void Type::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& Type::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.Type.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Type::set_name(const ::std::string& value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Type.name) +} +inline void Type::set_name(const char* value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Type.name) +} +inline void Type::set_name(const char* value, size_t size) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Type.name) +} +inline ::std::string* Type::mutable_name() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Type.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* Type::release_name() { + + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Type::set_allocated_name(::std::string* name) { + if (name != NULL) { + + } else { + + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Type.name) +} + +// repeated .google.protobuf.Field fields = 2; +inline int Type::fields_size() const { + return fields_.size(); +} +inline void Type::clear_fields() { + fields_.Clear(); +} +inline const ::google::protobuf::Field& Type::fields(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Type.fields) + return fields_.Get(index); +} +inline ::google::protobuf::Field* Type::mutable_fields(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Type.fields) + return fields_.Mutable(index); +} +inline ::google::protobuf::Field* Type::add_fields() { + // @@protoc_insertion_point(field_add:google.protobuf.Type.fields) + return fields_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Field >& +Type::fields() const { + // @@protoc_insertion_point(field_list:google.protobuf.Type.fields) + return fields_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::Field >* +Type::mutable_fields() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Type.fields) + return &fields_; +} + +// repeated string oneofs = 3; +inline int Type::oneofs_size() const { + return oneofs_.size(); +} +inline void Type::clear_oneofs() { + oneofs_.Clear(); +} +inline const ::std::string& Type::oneofs(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Type.oneofs) + return oneofs_.Get(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) { + // @@protoc_insertion_point(field_set:google.protobuf.Type.oneofs) + oneofs_.Mutable(index)->assign(value); +} +inline void Type::set_oneofs(int index, const char* value) { + 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::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(const char* value) { + 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 ::google::protobuf::RepeatedPtrField< ::std::string>& +Type::oneofs() const { + // @@protoc_insertion_point(field_list:google.protobuf.Type.oneofs) + return oneofs_; +} +inline ::google::protobuf::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::options_size() const { + return options_.size(); +} +inline void Type::clear_options() { + options_.Clear(); +} +inline const ::google::protobuf::Option& Type::options(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Type.options) + return options_.Get(index); +} +inline ::google::protobuf::Option* Type::mutable_options(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Type.options) + return options_.Mutable(index); +} +inline ::google::protobuf::Option* Type::add_options() { + // @@protoc_insertion_point(field_add:google.protobuf.Type.options) + return options_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >& +Type::options() const { + // @@protoc_insertion_point(field_list:google.protobuf.Type.options) + return options_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >* +Type::mutable_options() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Type.options) + return &options_; +} + +// optional .google.protobuf.SourceContext source_context = 5; +inline bool Type::has_source_context() const { + return !_is_default_instance_ && source_context_ != NULL; +} +inline void Type::clear_source_context() { + if (GetArenaNoVirtual() == NULL && source_context_ != NULL) delete source_context_; + source_context_ = NULL; +} +inline const ::google::protobuf::SourceContext& Type::source_context() const { + // @@protoc_insertion_point(field_get:google.protobuf.Type.source_context) + return source_context_ != NULL ? *source_context_ : *default_instance_->source_context_; +} +inline ::google::protobuf::SourceContext* Type::mutable_source_context() { + + if (source_context_ == NULL) { + source_context_ = new ::google::protobuf::SourceContext; + } + // @@protoc_insertion_point(field_mutable:google.protobuf.Type.source_context) + return source_context_; +} +inline ::google::protobuf::SourceContext* Type::release_source_context() { + + ::google::protobuf::SourceContext* temp = source_context_; + source_context_ = NULL; + return temp; +} +inline void Type::set_allocated_source_context(::google::protobuf::SourceContext* source_context) { + delete source_context_; + source_context_ = source_context; + if (source_context) { + + } else { + + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Type.source_context) +} + +// ------------------------------------------------------------------- + +// Field + +// optional .google.protobuf.Field.Kind kind = 1; +inline void Field::clear_kind() { + kind_ = 0; +} +inline ::google::protobuf::Field_Kind Field::kind() const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.kind) + return static_cast< ::google::protobuf::Field_Kind >(kind_); +} +inline void Field::set_kind(::google::protobuf::Field_Kind value) { + + kind_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Field.kind) +} + +// optional .google.protobuf.Field.Cardinality cardinality = 2; +inline void Field::clear_cardinality() { + cardinality_ = 0; +} +inline ::google::protobuf::Field_Cardinality Field::cardinality() const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.cardinality) + return static_cast< ::google::protobuf::Field_Cardinality >(cardinality_); +} +inline void Field::set_cardinality(::google::protobuf::Field_Cardinality value) { + + cardinality_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Field.cardinality) +} + +// optional int32 number = 3; +inline void Field::clear_number() { + number_ = 0; +} +inline ::google::protobuf::int32 Field::number() const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.number) + return number_; +} +inline void Field::set_number(::google::protobuf::int32 value) { + + number_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Field.number) +} + +// optional string name = 4; +inline void Field::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& Field::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Field::set_name(const ::std::string& value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Field.name) +} +inline void Field::set_name(const char* value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Field.name) +} +inline void Field::set_name(const char* value, size_t size) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Field.name) +} +inline ::std::string* Field::mutable_name() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Field.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* Field::release_name() { + + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Field::set_allocated_name(::std::string* name) { + if (name != NULL) { + + } else { + + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.name) +} + +// optional string type_url = 6; +inline void Field::clear_type_url() { + type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& Field::type_url() const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.type_url) + return type_url_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Field::set_type_url(const ::std::string& value) { + + type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Field.type_url) +} +inline void Field::set_type_url(const char* value) { + + type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Field.type_url) +} +inline void Field::set_type_url(const char* value, size_t size) { + + type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Field.type_url) +} +inline ::std::string* Field::mutable_type_url() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Field.type_url) + return type_url_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* Field::release_type_url() { + + return type_url_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Field::set_allocated_type_url(::std::string* type_url) { + if (type_url != NULL) { + + } else { + + } + type_url_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), type_url); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.type_url) +} + +// optional int32 oneof_index = 7; +inline void Field::clear_oneof_index() { + oneof_index_ = 0; +} +inline ::google::protobuf::int32 Field::oneof_index() const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.oneof_index) + return oneof_index_; +} +inline void Field::set_oneof_index(::google::protobuf::int32 value) { + + oneof_index_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Field.oneof_index) +} + +// optional bool packed = 8; +inline void Field::clear_packed() { + packed_ = false; +} +inline bool Field::packed() const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.packed) + return packed_; +} +inline void Field::set_packed(bool value) { + + packed_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Field.packed) +} + +// repeated .google.protobuf.Option options = 9; +inline int Field::options_size() const { + return options_.size(); +} +inline void Field::clear_options() { + options_.Clear(); +} +inline const ::google::protobuf::Option& Field::options(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Field.options) + return options_.Get(index); +} +inline ::google::protobuf::Option* Field::mutable_options(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Field.options) + return options_.Mutable(index); +} +inline ::google::protobuf::Option* Field::add_options() { + // @@protoc_insertion_point(field_add:google.protobuf.Field.options) + return options_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >& +Field::options() const { + // @@protoc_insertion_point(field_list:google.protobuf.Field.options) + return options_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >* +Field::mutable_options() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Field.options) + return &options_; +} + +// ------------------------------------------------------------------- + +// Enum + +// optional string name = 1; +inline void Enum::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& Enum::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.Enum.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Enum::set_name(const ::std::string& value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Enum.name) +} +inline void Enum::set_name(const char* value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Enum.name) +} +inline void Enum::set_name(const char* value, size_t size) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Enum.name) +} +inline ::std::string* Enum::mutable_name() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* Enum::release_name() { + + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Enum::set_allocated_name(::std::string* name) { + if (name != NULL) { + + } else { + + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Enum.name) +} + +// repeated .google.protobuf.EnumValue enumvalue = 2; +inline int Enum::enumvalue_size() const { + return enumvalue_.size(); +} +inline void Enum::clear_enumvalue() { + enumvalue_.Clear(); +} +inline const ::google::protobuf::EnumValue& Enum::enumvalue(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Enum.enumvalue) + return enumvalue_.Get(index); +} +inline ::google::protobuf::EnumValue* Enum::mutable_enumvalue(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.enumvalue) + return enumvalue_.Mutable(index); +} +inline ::google::protobuf::EnumValue* Enum::add_enumvalue() { + // @@protoc_insertion_point(field_add:google.protobuf.Enum.enumvalue) + return enumvalue_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValue >& +Enum::enumvalue() const { + // @@protoc_insertion_point(field_list:google.protobuf.Enum.enumvalue) + return enumvalue_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValue >* +Enum::mutable_enumvalue() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Enum.enumvalue) + return &enumvalue_; +} + +// repeated .google.protobuf.Option options = 3; +inline int Enum::options_size() const { + return options_.size(); +} +inline void Enum::clear_options() { + options_.Clear(); +} +inline const ::google::protobuf::Option& Enum::options(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.Enum.options) + return options_.Get(index); +} +inline ::google::protobuf::Option* Enum::mutable_options(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.options) + return options_.Mutable(index); +} +inline ::google::protobuf::Option* Enum::add_options() { + // @@protoc_insertion_point(field_add:google.protobuf.Enum.options) + return options_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >& +Enum::options() const { + // @@protoc_insertion_point(field_list:google.protobuf.Enum.options) + return options_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >* +Enum::mutable_options() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.Enum.options) + return &options_; +} + +// optional .google.protobuf.SourceContext source_context = 4; +inline bool Enum::has_source_context() const { + return !_is_default_instance_ && source_context_ != NULL; +} +inline void Enum::clear_source_context() { + if (GetArenaNoVirtual() == NULL && source_context_ != NULL) delete source_context_; + source_context_ = NULL; +} +inline const ::google::protobuf::SourceContext& Enum::source_context() const { + // @@protoc_insertion_point(field_get:google.protobuf.Enum.source_context) + return source_context_ != NULL ? *source_context_ : *default_instance_->source_context_; +} +inline ::google::protobuf::SourceContext* Enum::mutable_source_context() { + + if (source_context_ == NULL) { + source_context_ = new ::google::protobuf::SourceContext; + } + // @@protoc_insertion_point(field_mutable:google.protobuf.Enum.source_context) + return source_context_; +} +inline ::google::protobuf::SourceContext* Enum::release_source_context() { + + ::google::protobuf::SourceContext* temp = source_context_; + source_context_ = NULL; + return temp; +} +inline void Enum::set_allocated_source_context(::google::protobuf::SourceContext* source_context) { + delete source_context_; + source_context_ = source_context; + if (source_context) { + + } else { + + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Enum.source_context) +} + +// ------------------------------------------------------------------- + +// EnumValue + +// optional string name = 1; +inline void EnumValue::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& EnumValue::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumValue.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void EnumValue::set_name(const ::std::string& value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.EnumValue.name) +} +inline void EnumValue::set_name(const char* value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.EnumValue.name) +} +inline void EnumValue::set_name(const char* value, size_t size) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.EnumValue.name) +} +inline ::std::string* EnumValue::mutable_name() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValue.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* EnumValue::release_name() { + + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void EnumValue::set_allocated_name(::std::string* name) { + if (name != NULL) { + + } else { + + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.EnumValue.name) +} + +// optional int32 number = 2; +inline void EnumValue::clear_number() { + number_ = 0; +} +inline ::google::protobuf::int32 EnumValue::number() const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumValue.number) + return number_; +} +inline void EnumValue::set_number(::google::protobuf::int32 value) { + + number_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.EnumValue.number) +} + +// repeated .google.protobuf.Option options = 3; +inline int EnumValue::options_size() const { + return options_.size(); +} +inline void EnumValue::clear_options() { + options_.Clear(); +} +inline const ::google::protobuf::Option& EnumValue::options(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.EnumValue.options) + return options_.Get(index); +} +inline ::google::protobuf::Option* EnumValue::mutable_options(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.EnumValue.options) + return options_.Mutable(index); +} +inline ::google::protobuf::Option* EnumValue::add_options() { + // @@protoc_insertion_point(field_add:google.protobuf.EnumValue.options) + return options_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >& +EnumValue::options() const { + // @@protoc_insertion_point(field_list:google.protobuf.EnumValue.options) + return options_; +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >* +EnumValue::mutable_options() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumValue.options) + return &options_; +} + +// ------------------------------------------------------------------- + +// Option + +// optional string name = 1; +inline void Option::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& Option::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.Option.name) + return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Option::set_name(const ::std::string& value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.Option.name) +} +inline void Option::set_name(const char* value) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.Option.name) +} +inline void Option::set_name(const char* value, size_t size) { + + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.Option.name) +} +inline ::std::string* Option::mutable_name() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.Option.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* Option::release_name() { + + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void Option::set_allocated_name(::std::string* name) { + if (name != NULL) { + + } else { + + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Option.name) +} + +// optional .google.protobuf.Any value = 2; +inline bool Option::has_value() const { + return !_is_default_instance_ && value_ != NULL; +} +inline void Option::clear_value() { + if (GetArenaNoVirtual() == NULL && value_ != NULL) delete value_; + value_ = NULL; +} +inline const ::google::protobuf::Any& Option::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Option.value) + return value_ != NULL ? *value_ : *default_instance_->value_; +} +inline ::google::protobuf::Any* Option::mutable_value() { + + if (value_ == NULL) { + value_ = new ::google::protobuf::Any; + } + // @@protoc_insertion_point(field_mutable:google.protobuf.Option.value) + return value_; +} +inline ::google::protobuf::Any* Option::release_value() { + + ::google::protobuf::Any* temp = value_; + value_ = NULL; + return temp; +} +inline void Option::set_allocated_value(::google::protobuf::Any* value) { + delete value_; + value_ = value; + if (value) { + + } else { + + } + // @@protoc_insertion_point(field_set_allocated:google.protobuf.Option.value) +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace protobuf +} // namespace google + +#ifndef SWIG +namespace google { +namespace protobuf { + +template <> struct is_proto_enum< ::google::protobuf::Field_Kind> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::Field_Kind>() { + return ::google::protobuf::Field_Kind_descriptor(); +} +template <> struct is_proto_enum< ::google::protobuf::Field_Cardinality> : ::google::protobuf::internal::true_type {}; +template <> +inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::Field_Cardinality>() { + return ::google::protobuf::Field_Cardinality_descriptor(); +} + +} // namespace protobuf +} // namespace google +#endif // SWIG + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_google_2fprotobuf_2ftype_2eproto__INCLUDED diff --git a/src/google/protobuf/type.proto b/src/google/protobuf/type.proto index 04165c81..ace5d995 100644 --- a/src/google/protobuf/type.proto +++ b/src/google/protobuf/type.proto @@ -37,6 +37,7 @@ import "google/protobuf/source_context.proto"; option java_multiple_files = true; option java_outer_classname = "TypeProto"; option java_package = "com.google.protobuf"; +option objc_class_prefix = "GPB"; // A light-weight descriptor for a proto message type. diff --git a/src/google/protobuf/unittest.proto b/src/google/protobuf/unittest.proto index 745f77c5..834c9b56 100644 --- a/src/google/protobuf/unittest.proto +++ b/src/google/protobuf/unittest.proto @@ -42,6 +42,7 @@ 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; +option csharp_namespace = "Google.ProtocolBuffers.TestProtos"; import "google/protobuf/unittest_import.proto"; @@ -184,6 +185,7 @@ message TestAllTypes { message NestedTestAllTypes { optional NestedTestAllTypes child = 1; optional TestAllTypes payload = 2; + repeated NestedTestAllTypes repeated_child = 3; } message TestDeprecatedFields { @@ -202,6 +204,11 @@ enum ForeignEnum { FOREIGN_BAZ = 6; } +message TestReservedFields { + reserved 2, 15, 9 to 11; + reserved "bar", "baz"; +} + message TestAllExtensions { extensions 1 to max; } diff --git a/src/google/protobuf/unittest_custom_options.proto b/src/google/protobuf/unittest_custom_options.proto index d4d6e869..8f9fb582 100644 --- a/src/google/protobuf/unittest_custom_options.proto +++ b/src/google/protobuf/unittest_custom_options.proto @@ -41,6 +41,7 @@ syntax = "proto2"; option cc_generic_services = true; // auto-added option java_generic_services = true; // auto-added option py_generic_services = true; +option csharp_namespace = "Google.ProtocolBuffers.TestProtos"; // A custom file option (defined below). option (file_opt1) = 9876543210; diff --git a/src/google/protobuf/unittest_drop_unknown_fields.proto b/src/google/protobuf/unittest_drop_unknown_fields.proto index 66b31acf..faaddc6e 100644 --- a/src/google/protobuf/unittest_drop_unknown_fields.proto +++ b/src/google/protobuf/unittest_drop_unknown_fields.proto @@ -31,6 +31,9 @@ syntax = "proto3"; package unittest_drop_unknown_fields; +option objc_class_prefix = "DropUnknowns"; + +option csharp_namespace = "Google.ProtocolBuffers.TestProtos"; message Foo { enum NestedEnum { @@ -38,8 +41,8 @@ message Foo { BAR = 1; BAZ = 2; } - optional int32 int32_value = 1; - optional NestedEnum enum_value = 2; + int32 int32_value = 1; + NestedEnum enum_value = 2; } message FooWithExtraFields { @@ -49,7 +52,7 @@ message FooWithExtraFields { BAZ = 2; QUX = 3; } - optional int32 int32_value = 1; - optional NestedEnum enum_value = 2; - optional int32 extra_int32_value = 3; + int32 int32_value = 1; + NestedEnum enum_value = 2; + int32 extra_int32_value = 3; } diff --git a/src/google/protobuf/unittest_embed_optimize_for.proto b/src/google/protobuf/unittest_embed_optimize_for.proto index d8b0f9b9..c4ccccb7 100644 --- a/src/google/protobuf/unittest_embed_optimize_for.proto +++ b/src/google/protobuf/unittest_embed_optimize_for.proto @@ -39,6 +39,8 @@ import "google/protobuf/unittest_optimize_for.proto"; package protobuf_unittest; +option csharp_namespace = "Google.ProtocolBuffers.TestProtos"; + // We optimize for speed here, but we are importing a proto that is optimized // for code size. option optimize_for = SPEED; diff --git a/src/google/protobuf/unittest_enormous_descriptor.proto b/src/google/protobuf/unittest_enormous_descriptor.proto index 2250261d..f8fcc9c0 100644 --- a/src/google/protobuf/unittest_enormous_descriptor.proto +++ b/src/google/protobuf/unittest_enormous_descriptor.proto @@ -33,12 +33,14 @@ // 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 the string literal length limit in Java. +// descriptors over 64k don't break language-specific limits in generated code, +// such as the string literal length limit in Java. syntax = "proto2"; package google.protobuf; option java_package = "com.google.protobuf"; +option csharp_namespace = "Google.ProtocolBuffers.TestProtos"; // Avoid generating insanely long methods. option optimize_for = CODE_SIZE; diff --git a/src/google/protobuf/unittest_import.proto b/src/google/protobuf/unittest_import.proto index 7e165220..ae2e90b8 100644 --- a/src/google/protobuf/unittest_import.proto +++ b/src/google/protobuf/unittest_import.proto @@ -47,6 +47,7 @@ option cc_enable_arenas = true; // Exercise the java_package option. option java_package = "com.google.protobuf.test"; +option csharp_namespace = "Google.ProtocolBuffers.TestProtos"; // Do not set a java_outer_classname here to verify that Proto2 works without // one. diff --git a/src/google/protobuf/unittest_import_lite.proto b/src/google/protobuf/unittest_import_lite.proto index a7afa452..ca208582 100644 --- a/src/google/protobuf/unittest_import_lite.proto +++ b/src/google/protobuf/unittest_import_lite.proto @@ -38,6 +38,7 @@ package protobuf_unittest_import; option optimize_for = LITE_RUNTIME; option java_package = "com.google.protobuf"; +option csharp_namespace = "Google.ProtocolBuffers.TestProtos"; import public "google/protobuf/unittest_import_public_lite.proto"; diff --git a/src/google/protobuf/unittest_import_public.proto b/src/google/protobuf/unittest_import_public.proto index ffaf7736..0bc5d617 100644 --- a/src/google/protobuf/unittest_import_public.proto +++ b/src/google/protobuf/unittest_import_public.proto @@ -35,6 +35,7 @@ syntax = "proto2"; package protobuf_unittest_import; option java_package = "com.google.protobuf.test"; +option csharp_namespace = "Google.ProtocolBuffers.TestProtos"; message PublicImportMessage { optional int32 e = 1; diff --git a/src/google/protobuf/unittest_import_public_lite.proto b/src/google/protobuf/unittest_import_public_lite.proto index 33549c22..231ab9dd 100644 --- a/src/google/protobuf/unittest_import_public_lite.proto +++ b/src/google/protobuf/unittest_import_public_lite.proto @@ -37,6 +37,7 @@ package protobuf_unittest_import; option optimize_for = LITE_RUNTIME; option java_package = "com.google.protobuf"; +option csharp_namespace = "Google.ProtocolBuffers.TestProtos"; message PublicImportMessageLite { optional int32 e = 1; diff --git a/src/google/protobuf/unittest_lite.proto b/src/google/protobuf/unittest_lite.proto index 662c0e46..0040874b 100644 --- a/src/google/protobuf/unittest_lite.proto +++ b/src/google/protobuf/unittest_lite.proto @@ -40,6 +40,7 @@ import "google/protobuf/unittest_import_lite.proto"; option optimize_for = LITE_RUNTIME; option java_package = "com.google.protobuf"; +option csharp_namespace = "Google.ProtocolBuffers.TestProtos"; // Same as TestAllTypes but with the lite runtime. message TestAllTypesLite { diff --git a/src/google/protobuf/unittest_lite_imports_nonlite.proto b/src/google/protobuf/unittest_lite_imports_nonlite.proto index 132d6a82..d955cc14 100644 --- a/src/google/protobuf/unittest_lite_imports_nonlite.proto +++ b/src/google/protobuf/unittest_lite_imports_nonlite.proto @@ -38,6 +38,7 @@ package protobuf_unittest; import "google/protobuf/unittest.proto"; option optimize_for = LITE_RUNTIME; +option csharp_namespace = "Google.ProtocolBuffers.TestProtos"; message TestLiteImportsNonlite { optional TestAllTypes message = 1; diff --git a/src/google/protobuf/unittest_mset.proto b/src/google/protobuf/unittest_mset.proto index 3aa31fa9..425c9a5a 100644 --- a/src/google/protobuf/unittest_mset.proto +++ b/src/google/protobuf/unittest_mset.proto @@ -39,6 +39,7 @@ package protobuf_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 { diff --git a/src/google/protobuf/unittest_no_field_presence.proto b/src/google/protobuf/unittest_no_field_presence.proto index e04da0ac..f5cc4cc3 100644 --- a/src/google/protobuf/unittest_no_field_presence.proto +++ b/src/google/protobuf/unittest_no_field_presence.proto @@ -37,11 +37,13 @@ import "google/protobuf/unittest.proto"; package proto2_nofieldpresence_unittest; +option csharp_namespace = "Google.ProtocolBuffers.TestProtos.Proto3"; + // This proto includes every type of field in both singular and repeated // forms. message TestAllTypes { message NestedMessage { - optional int32 bb = 1; + int32 bb = 1; } enum NestedEnum { @@ -53,36 +55,36 @@ message TestAllTypes { // Singular // TODO: remove 'optional' labels as soon as CL 69188077 is LGTM'd to make // 'optional' optional. - 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 ForeignMessage optional_foreign_message = 19; - optional protobuf_unittest.TestAllTypes optional_proto2_message = 20; - - optional NestedEnum optional_nested_enum = 21; - optional ForeignEnum optional_foreign_enum = 22; + 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; - optional string optional_string_piece = 24 [ctype=STRING_PIECE]; - optional string optional_cord = 25 [ctype=CORD]; + string optional_string_piece = 24 [ctype=STRING_PIECE]; + string optional_cord = 25 [ctype=CORD]; - optional NestedMessage optional_lazy_message = 30 [lazy=true]; + NestedMessage optional_lazy_message = 30 [lazy=true]; // Repeated repeated int32 repeated_int32 = 31; @@ -122,13 +124,13 @@ message TestAllTypes { } message TestProto2Required { - optional protobuf_unittest.TestRequired proto2 = 1; + protobuf_unittest.TestRequired proto2 = 1; } // Define these after TestAllTypes to make sure the compiler can handle // that. message ForeignMessage { - optional int32 c = 1; + int32 c = 1; } enum ForeignEnum { diff --git a/src/google/protobuf/unittest_optimize_for.proto b/src/google/protobuf/unittest_optimize_for.proto index ee9cc7bd..2bcd16e4 100644 --- a/src/google/protobuf/unittest_optimize_for.proto +++ b/src/google/protobuf/unittest_optimize_for.proto @@ -40,6 +40,7 @@ import "google/protobuf/unittest.proto"; package protobuf_unittest; option optimize_for = CODE_SIZE; +option csharp_namespace = "Google.ProtocolBuffers.TestProtos"; message TestOptimizedForSize { optional int32 i = 1; diff --git a/src/google/protobuf/unittest_preserve_unknown_enum.proto b/src/google/protobuf/unittest_preserve_unknown_enum.proto index 67e57499..abc3de28 100644 --- a/src/google/protobuf/unittest_preserve_unknown_enum.proto +++ b/src/google/protobuf/unittest_preserve_unknown_enum.proto @@ -31,6 +31,9 @@ syntax = "proto3"; package proto3_preserve_unknown_enum_unittest; +option objc_class_prefix = "UnknownEnums"; + +option csharp_namespace = "Google.ProtocolBuffers.TestProtos"; enum MyEnum { FOO = 0; @@ -46,7 +49,7 @@ enum MyEnumPlusExtra { } message MyMessage { - optional MyEnum e = 1; + 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 @@ -57,7 +60,7 @@ message MyMessage { } message MyMessagePlusExtra { - optional MyEnumPlusExtra e = 1; + 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]; diff --git a/src/google/protobuf/unittest_preserve_unknown_enum2.proto b/src/google/protobuf/unittest_preserve_unknown_enum2.proto index adf42968..168b2407 100644 --- a/src/google/protobuf/unittest_preserve_unknown_enum2.proto +++ b/src/google/protobuf/unittest_preserve_unknown_enum2.proto @@ -32,6 +32,8 @@ syntax = "proto2"; package proto2_preserve_unknown_enum_unittest; +option csharp_namespace = "Google.ProtocolBuffers.TestProtos"; + enum MyEnum { FOO = 0; BAR = 1; diff --git a/src/google/protobuf/unittest_proto3_arena.proto b/src/google/protobuf/unittest_proto3_arena.proto index 6d7bada8..b835a6ba 100644 --- a/src/google/protobuf/unittest_proto3_arena.proto +++ b/src/google/protobuf/unittest_proto3_arena.proto @@ -43,7 +43,7 @@ message TestAllTypes { // 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; + int32 bb = 1; } enum NestedEnum { @@ -55,46 +55,47 @@ message TestAllTypes { } // 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; + 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; - optional string optional_string_piece = 24 [ctype=STRING_PIECE]; - optional string optional_cord = 25 [ctype=CORD]; + string optional_string_piece = 24 [ctype=STRING_PIECE]; + string optional_cord = 25 [ctype=CORD]; // Defined in unittest_import_public.proto - optional protobuf_unittest_import.PublicImportMessage + protobuf_unittest_import.PublicImportMessage optional_public_import_message = 26; - optional NestedMessage optional_lazy_message = 27 [lazy=true]; + NestedMessage optional_lazy_message = 27 [lazy=true]; // Repeated repeated int32 repeated_int32 = 31; @@ -113,9 +114,10 @@ message TestAllTypes { repeated string repeated_string = 44; repeated bytes repeated_bytes = 45; - repeated group RepeatedGroup = 46 { - optional int32 a = 47; - } + // 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; @@ -161,6 +163,24 @@ message TestPackedTypes { 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 recusively nested message. message NestedTestAllTypes { NestedTestAllTypes child = 1; @@ -170,7 +190,7 @@ message NestedTestAllTypes { // Define these after TestAllTypes to make sure the compiler can handle // that. message ForeignMessage { - optional int32 c = 1; + int32 c = 1; } enum ForeignEnum { diff --git a/src/google/protobuf/unittest_well_known_types.proto b/src/google/protobuf/unittest_well_known_types.proto new file mode 100644 index 00000000..e157260e --- /dev/null +++ b/src/google/protobuf/unittest_well_known_types.proto @@ -0,0 +1,31 @@ +syntax = "proto3"; + +package protobuf_unittest; + +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. +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.Int32Value int32_field = 10; +} diff --git a/src/google/protobuf/unknown_enum_test.proto b/src/google/protobuf/unknown_enum_test.proto index caafadcd..3c549cc7 100644 --- a/src/google/protobuf/unknown_enum_test.proto +++ b/src/google/protobuf/unknown_enum_test.proto @@ -36,6 +36,7 @@ syntax = "proto2"; package google.protobuf.util; +option csharp_namespace = "Google.ProtocolBuffers.TestProtos"; message DownRevision { enum Enum { diff --git a/src/google/protobuf/unknown_field_set.cc b/src/google/protobuf/unknown_field_set.cc index e15280c8..76644900 100644 --- a/src/google/protobuf/unknown_field_set.cc +++ b/src/google/protobuf/unknown_field_set.cc @@ -93,7 +93,7 @@ void UnknownFieldSet::InternalMergeFrom(const UnknownFieldSet& other) { fields_ = new vector<UnknownField>(); for (int i = 0; i < other_field_count; i++) { fields_->push_back((*other.fields_)[i]); - fields_->back().DeepCopy(); + fields_->back().DeepCopy((*other.fields_)[i]); } } } @@ -104,7 +104,7 @@ void UnknownFieldSet::MergeFrom(const UnknownFieldSet& other) { if (fields_ == NULL) fields_ = new vector<UnknownField>(); for (int i = 0; i < other_field_count; i++) { fields_->push_back((*other.fields_)[i]); - fields_->back().DeepCopy(); + fields_->back().DeepCopy((*other.fields_)[i]); } } } @@ -202,7 +202,7 @@ UnknownFieldSet* UnknownFieldSet::AddGroup(int number) { void UnknownFieldSet::AddField(const UnknownField& field) { if (fields_ == NULL) fields_ = new vector<UnknownField>(); fields_->push_back(field); - fields_->back().DeepCopy(); + fields_->back().DeepCopy(field); } void UnknownFieldSet::DeleteSubrange(int start, int num) { @@ -303,7 +303,7 @@ void UnknownField::Reset() { } } -void UnknownField::DeepCopy() { +void UnknownField::DeepCopy(const UnknownField& other) { switch (type()) { case UnknownField::TYPE_LENGTH_DELIMITED: length_delimited_.string_value_ = new string( diff --git a/src/google/protobuf/unknown_field_set.h b/src/google/protobuf/unknown_field_set.h index 987b1979..6781cd0f 100644 --- a/src/google/protobuf/unknown_field_set.h +++ b/src/google/protobuf/unknown_field_set.h @@ -216,7 +216,7 @@ class LIBPROTOBUF_EXPORT UnknownField { void Reset(); // Make a deep copy of any pointers in this UnknownField. - void DeepCopy(); + void DeepCopy(const UnknownField& other); // Set the wire type of this UnknownField. Should only be used when this // UnknownField is being created. diff --git a/src/google/protobuf/well_known_types_unittest.cc b/src/google/protobuf/well_known_types_unittest.cc new file mode 100644 index 00000000..c9a9aa10 --- /dev/null +++ b/src/google/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 <google/protobuf/unittest_well_known_types.pb.h> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/testing/googletest.h> +#include <gtest/gtest.h> +#include <google/protobuf/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/src/google/protobuf/wire_format.cc b/src/google/protobuf/wire_format.cc index c5bbbf2e..54cd653a 100644 --- a/src/google/protobuf/wire_format.cc +++ b/src/google/protobuf/wire_format.cc @@ -829,7 +829,7 @@ void WireFormat::SerializeFieldWithCachedSizes( count = 1; } - const bool is_packed = field->options().packed(); + const bool is_packed = field->is_packed(); if (is_packed && count > 0) { WireFormatLite::WriteTag(field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output); @@ -996,7 +996,7 @@ int WireFormat::FieldByteSize( const int data_size = FieldDataOnlyByteSize(field, message); int our_size = data_size; - if (field->options().packed()) { + 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 diff --git a/src/google/protobuf/wire_format_lite.h b/src/google/protobuf/wire_format_lite.h index 76bc75a1..ac83abdc 100644 --- a/src/google/protobuf/wire_format_lite.h +++ b/src/google/protobuf/wire_format_lite.h @@ -330,6 +330,17 @@ class LIBPROTOBUF_EXPORT WireFormatLite { template<typename MessageType> static inline bool ReadMessageNoVirtual(input, MessageType* value); + // The same, but do not modify input's recursion depth. This is useful + // when reading a bunch of groups or messages in a loop, because then the + // recursion depth can be incremented before the loop and decremented after. + template<typename MessageType> + static inline bool ReadGroupNoVirtualNoRecursionDepth(field_number, input, + MessageType* value); + + template<typename MessageType> + static inline bool ReadMessageNoVirtualNoRecursionDepth(input, + MessageType* 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. diff --git a/src/google/protobuf/wire_format_lite_inl.h b/src/google/protobuf/wire_format_lite_inl.h index 129fc63f..d073ff92 100644 --- a/src/google/protobuf/wire_format_lite_inl.h +++ b/src/google/protobuf/wire_format_lite_inl.h @@ -470,7 +470,7 @@ inline bool WireFormatLite::ReadGroupNoVirtual( if (!value-> MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input)) return false; - input->DecrementRecursionDepth(); + 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; @@ -478,6 +478,14 @@ inline bool WireFormatLite::ReadGroupNoVirtual( return true; } template<typename MessageType_WorkAroundCppLookupDefect> +inline bool WireFormatLite::ReadGroupNoVirtualNoRecursionDepth( + int field_number, io::CodedInputStream* input, + MessageType_WorkAroundCppLookupDefect* value) { + return value->MessageType_WorkAroundCppLookupDefect:: + MergePartialFromCodedStream(input) && + input->LastTagWas(MakeTag(field_number, WIRETYPE_END_GROUP)); +} +template<typename MessageType_WorkAroundCppLookupDefect> inline bool WireFormatLite::ReadMessageNoVirtual( io::CodedInputStream* input, MessageType_WorkAroundCppLookupDefect* value) { uint32 length; @@ -491,6 +499,17 @@ inline bool WireFormatLite::ReadMessageNoVirtual( // tag. return input->DecrementRecursionDepthAndPopLimit(p.first); } +template<typename MessageType_WorkAroundCppLookupDefect> +inline bool WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + io::CodedInputStream* input, MessageType_WorkAroundCppLookupDefect* value) { + io::CodedInputStream::Limit old_limit = input->ReadLengthAndPushLimit(); + if (!value-> + MessageType_WorkAroundCppLookupDefect::MergePartialFromCodedStream(input)) + return false; + // Make sure that parsing stopped when the limit was hit, not at an endgroup + // tag. + return input->CheckEntireMessageConsumedAndPopLimit(old_limit); +} // =================================================================== diff --git a/src/google/protobuf/wire_format_unittest.cc b/src/google/protobuf/wire_format_unittest.cc index 46650605..4b151f97 100644 --- a/src/google/protobuf/wire_format_unittest.cc +++ b/src/google/protobuf/wire_format_unittest.cc @@ -38,6 +38,7 @@ #include <google/protobuf/io/zero_copy_stream_impl.h> #include <google/protobuf/io/coded_stream.h> #include <google/protobuf/unittest.pb.h> +#include <google/protobuf/unittest_proto3_arena.pb.h> #include <google/protobuf/unittest_mset.pb.h> #include <google/protobuf/test_util.h> @@ -794,6 +795,137 @@ TEST(WireFormatTest, CompatibleTypes) { ASSERT_EQ(static_cast<uint32>(data), msg5.data()); } +class Proto3PrimitiveRepeatedWireFormatTest + : public ::testing::TestWithParam<bool> { + protected: + 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_NestedEnum_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_NestedEnum_FOO, + message.repeated_nested_enum(0)); + } + + template <class Proto> + void TestProto3PrimitiveRepeatedFields(Proto* message, + const string& expected) { + SetProto3PrimitiveRepeatedFields(message); + + int size = message->ByteSize(); + + // Serialize using the generated code. + string generated_data; + { + io::StringOutputStream raw_output(&generated_data); + io::CodedOutputStream output(&raw_output); + message->SerializeWithCachedSizes(&output); + ASSERT_FALSE(output.HadError()); + } + + EXPECT_TRUE(expected == generated_data); + + message->Clear(); + message->ParseFromString(generated_data); + ExpectProto3PrimitiveRepeatedFieldsSet(*message); + + // Serialize using the dynamic code. + 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); + + message->Clear(); + io::CodedInputStream input( + reinterpret_cast<const uint8*>(dynamic_data.data()), + dynamic_data.size()); + WireFormat::ParseAndMergePartial(&input, message); + ExpectProto3PrimitiveRepeatedFieldsSet(*message); + } +}; +INSTANTIATE_TEST_CASE_P(SetPacked, + Proto3PrimitiveRepeatedWireFormatTest, + ::testing::Values(false, true)); + +TEST_P(Proto3PrimitiveRepeatedWireFormatTest, Proto3PrimitiveRepeated) { + proto3_arena_unittest::TestAllTypes packed_message; + proto3_arena_unittest::TestUnpackedTypes unpacked_message; + + const string packedExpected( + "\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); + + const string unpackedExpected( + "\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); + + if (GetParam()) { + TestProto3PrimitiveRepeatedFields(&packed_message, packedExpected); + } else { + TestProto3PrimitiveRepeatedFields(&unpacked_message, unpackedExpected); + } +} + class WireFormatInvalidInputTest : public testing::Test { protected: // Make a serialized TestAllTypes in which the field optional_nested_message diff --git a/src/google/protobuf/wrappers.pb.cc b/src/google/protobuf/wrappers.pb.cc new file mode 100644 index 00000000..ffc77f1c --- /dev/null +++ b/src/google/protobuf/wrappers.pb.cc @@ -0,0 +1,2419 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/wrappers.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include "google/protobuf/wrappers.pb.h" + +#include <algorithm> + +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/once.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/wire_format_lite_inl.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/generated_message_reflection.h> +#include <google/protobuf/reflection_ops.h> +#include <google/protobuf/wire_format.h> +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { + +namespace { + +const ::google::protobuf::Descriptor* DoubleValue_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + DoubleValue_reflection_ = NULL; +const ::google::protobuf::Descriptor* FloatValue_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + FloatValue_reflection_ = NULL; +const ::google::protobuf::Descriptor* Int64Value_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Int64Value_reflection_ = NULL; +const ::google::protobuf::Descriptor* UInt64Value_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + UInt64Value_reflection_ = NULL; +const ::google::protobuf::Descriptor* Int32Value_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + Int32Value_reflection_ = NULL; +const ::google::protobuf::Descriptor* UInt32Value_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + UInt32Value_reflection_ = NULL; +const ::google::protobuf::Descriptor* BoolValue_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + BoolValue_reflection_ = NULL; +const ::google::protobuf::Descriptor* StringValue_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + StringValue_reflection_ = NULL; +const ::google::protobuf::Descriptor* BytesValue_descriptor_ = NULL; +const ::google::protobuf::internal::GeneratedMessageReflection* + BytesValue_reflection_ = NULL; + +} // namespace + + +void protobuf_AssignDesc_google_2fprotobuf_2fwrappers_2eproto() { + protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto(); + const ::google::protobuf::FileDescriptor* file = + ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName( + "google/protobuf/wrappers.proto"); + GOOGLE_CHECK(file != NULL); + DoubleValue_descriptor_ = file->message_type(0); + static const int DoubleValue_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DoubleValue, value_), + }; + DoubleValue_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + DoubleValue_descriptor_, + DoubleValue::default_instance_, + DoubleValue_offsets_, + -1, + -1, + -1, + sizeof(DoubleValue), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DoubleValue, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DoubleValue, _is_default_instance_)); + FloatValue_descriptor_ = file->message_type(1); + static const int FloatValue_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FloatValue, value_), + }; + FloatValue_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + FloatValue_descriptor_, + FloatValue::default_instance_, + FloatValue_offsets_, + -1, + -1, + -1, + sizeof(FloatValue), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FloatValue, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FloatValue, _is_default_instance_)); + Int64Value_descriptor_ = file->message_type(2); + static const int Int64Value_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Int64Value, value_), + }; + Int64Value_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + Int64Value_descriptor_, + Int64Value::default_instance_, + Int64Value_offsets_, + -1, + -1, + -1, + sizeof(Int64Value), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Int64Value, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Int64Value, _is_default_instance_)); + UInt64Value_descriptor_ = file->message_type(3); + static const int UInt64Value_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UInt64Value, value_), + }; + UInt64Value_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + UInt64Value_descriptor_, + UInt64Value::default_instance_, + UInt64Value_offsets_, + -1, + -1, + -1, + sizeof(UInt64Value), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UInt64Value, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UInt64Value, _is_default_instance_)); + Int32Value_descriptor_ = file->message_type(4); + static const int Int32Value_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Int32Value, value_), + }; + Int32Value_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + Int32Value_descriptor_, + Int32Value::default_instance_, + Int32Value_offsets_, + -1, + -1, + -1, + sizeof(Int32Value), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Int32Value, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Int32Value, _is_default_instance_)); + UInt32Value_descriptor_ = file->message_type(5); + static const int UInt32Value_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UInt32Value, value_), + }; + UInt32Value_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + UInt32Value_descriptor_, + UInt32Value::default_instance_, + UInt32Value_offsets_, + -1, + -1, + -1, + sizeof(UInt32Value), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UInt32Value, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UInt32Value, _is_default_instance_)); + BoolValue_descriptor_ = file->message_type(6); + static const int BoolValue_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BoolValue, value_), + }; + BoolValue_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + BoolValue_descriptor_, + BoolValue::default_instance_, + BoolValue_offsets_, + -1, + -1, + -1, + sizeof(BoolValue), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BoolValue, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BoolValue, _is_default_instance_)); + StringValue_descriptor_ = file->message_type(7); + static const int StringValue_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StringValue, value_), + }; + StringValue_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + StringValue_descriptor_, + StringValue::default_instance_, + StringValue_offsets_, + -1, + -1, + -1, + sizeof(StringValue), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StringValue, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StringValue, _is_default_instance_)); + BytesValue_descriptor_ = file->message_type(8); + static const int BytesValue_offsets_[1] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BytesValue, value_), + }; + BytesValue_reflection_ = + ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection( + BytesValue_descriptor_, + BytesValue::default_instance_, + BytesValue_offsets_, + -1, + -1, + -1, + sizeof(BytesValue), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BytesValue, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BytesValue, _is_default_instance_)); +} + +namespace { + +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_); +inline void protobuf_AssignDescriptorsOnce() { + ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_, + &protobuf_AssignDesc_google_2fprotobuf_2fwrappers_2eproto); +} + +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + DoubleValue_descriptor_, &DoubleValue::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + FloatValue_descriptor_, &FloatValue::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Int64Value_descriptor_, &Int64Value::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + UInt64Value_descriptor_, &UInt64Value::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + Int32Value_descriptor_, &Int32Value::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + UInt32Value_descriptor_, &UInt32Value::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + BoolValue_descriptor_, &BoolValue::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + StringValue_descriptor_, &StringValue::default_instance()); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( + BytesValue_descriptor_, &BytesValue::default_instance()); +} + +} // namespace + +void protobuf_ShutdownFile_google_2fprotobuf_2fwrappers_2eproto() { + delete DoubleValue::default_instance_; + delete DoubleValue_reflection_; + delete FloatValue::default_instance_; + delete FloatValue_reflection_; + delete Int64Value::default_instance_; + delete Int64Value_reflection_; + delete UInt64Value::default_instance_; + delete UInt64Value_reflection_; + delete Int32Value::default_instance_; + delete Int32Value_reflection_; + delete UInt32Value::default_instance_; + delete UInt32Value_reflection_; + delete BoolValue::default_instance_; + delete BoolValue_reflection_; + delete StringValue::default_instance_; + delete StringValue_reflection_; + delete BytesValue::default_instance_; + delete BytesValue_reflection_; +} + +void protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto() { + static bool already_here = false; + if (already_here) return; + already_here = true; + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + "\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(\014BE\n\023com" + ".google.protobufB\rWrappersProtoP\001\242\002\003GPB\252" + "\002\026Google.ProtocolBuffersb\006proto3", 392); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "google/protobuf/wrappers.proto", &protobuf_RegisterTypes); + DoubleValue::default_instance_ = new DoubleValue(); + FloatValue::default_instance_ = new FloatValue(); + Int64Value::default_instance_ = new Int64Value(); + UInt64Value::default_instance_ = new UInt64Value(); + Int32Value::default_instance_ = new Int32Value(); + UInt32Value::default_instance_ = new UInt32Value(); + BoolValue::default_instance_ = new BoolValue(); + StringValue::default_instance_ = new StringValue(); + BytesValue::default_instance_ = new BytesValue(); + DoubleValue::default_instance_->InitAsDefaultInstance(); + FloatValue::default_instance_->InitAsDefaultInstance(); + Int64Value::default_instance_->InitAsDefaultInstance(); + UInt64Value::default_instance_->InitAsDefaultInstance(); + Int32Value::default_instance_->InitAsDefaultInstance(); + UInt32Value::default_instance_->InitAsDefaultInstance(); + BoolValue::default_instance_->InitAsDefaultInstance(); + StringValue::default_instance_->InitAsDefaultInstance(); + BytesValue::default_instance_->InitAsDefaultInstance(); + ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_google_2fprotobuf_2fwrappers_2eproto); +} + +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer_google_2fprotobuf_2fwrappers_2eproto { + StaticDescriptorInitializer_google_2fprotobuf_2fwrappers_2eproto() { + protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto(); + } +} static_descriptor_initializer_google_2fprotobuf_2fwrappers_2eproto_; + +namespace { + +static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD; +static void MergeFromFail(int line) { + GOOGLE_CHECK(false) << __FILE__ << ":" << line; +} + +} // namespace + + +// =================================================================== + +#ifndef _MSC_VER +const int DoubleValue::kValueFieldNumber; +#endif // !_MSC_VER + +DoubleValue::DoubleValue() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:google.protobuf.DoubleValue) +} + +void DoubleValue::InitAsDefaultInstance() { + _is_default_instance_ = true; +} + +DoubleValue::DoubleValue(const DoubleValue& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:google.protobuf.DoubleValue) +} + +void DoubleValue::SharedCtor() { + _is_default_instance_ = false; + _cached_size_ = 0; + value_ = 0; +} + +DoubleValue::~DoubleValue() { + // @@protoc_insertion_point(destructor:google.protobuf.DoubleValue) + SharedDtor(); +} + +void DoubleValue::SharedDtor() { + if (this != default_instance_) { + } +} + +void DoubleValue::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* DoubleValue::descriptor() { + protobuf_AssignDescriptorsOnce(); + return DoubleValue_descriptor_; +} + +const DoubleValue& DoubleValue::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto(); + return *default_instance_; +} + +DoubleValue* DoubleValue::default_instance_ = NULL; + +DoubleValue* DoubleValue::New(::google::protobuf::Arena* arena) const { + DoubleValue* n = new DoubleValue; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void DoubleValue::Clear() { + value_ = 0; +} + +bool DoubleValue::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:google.protobuf.DoubleValue) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional double value = 1; + case 1: { + if (tag == 9) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>( + input, &value_))); + + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:google.protobuf.DoubleValue) + return true; +failure: + // @@protoc_insertion_point(parse_failure:google.protobuf.DoubleValue) + return false; +#undef DO_ +} + +void DoubleValue::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:google.protobuf.DoubleValue) + // optional double value = 1; + if (this->value() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteDouble(1, this->value(), output); + } + + // @@protoc_insertion_point(serialize_end:google.protobuf.DoubleValue) +} + +::google::protobuf::uint8* DoubleValue::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DoubleValue) + // optional double value = 1; + if (this->value() != 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(1, this->value(), target); + } + + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.DoubleValue) + return target; +} + +int DoubleValue::ByteSize() const { + int total_size = 0; + + // optional double value = 1; + if (this->value() != 0) { + total_size += 1 + 8; + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void DoubleValue::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const DoubleValue* source = + ::google::protobuf::internal::DynamicCastToGenerated<const DoubleValue>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void DoubleValue::MergeFrom(const DoubleValue& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from.value() != 0) { + set_value(from.value()); + } +} + +void DoubleValue::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void DoubleValue::CopyFrom(const DoubleValue& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool DoubleValue::IsInitialized() const { + + return true; +} + +void DoubleValue::Swap(DoubleValue* other) { + if (other == this) return; + InternalSwap(other); +} +void DoubleValue::InternalSwap(DoubleValue* other) { + std::swap(value_, other->value_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata DoubleValue::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = DoubleValue_descriptor_; + metadata.reflection = DoubleValue_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// DoubleValue + +// optional double value = 1; +void DoubleValue::clear_value() { + value_ = 0; +} + double DoubleValue::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.DoubleValue.value) + return value_; +} + void DoubleValue::set_value(double value) { + + value_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.DoubleValue.value) +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// =================================================================== + +#ifndef _MSC_VER +const int FloatValue::kValueFieldNumber; +#endif // !_MSC_VER + +FloatValue::FloatValue() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:google.protobuf.FloatValue) +} + +void FloatValue::InitAsDefaultInstance() { + _is_default_instance_ = true; +} + +FloatValue::FloatValue(const FloatValue& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:google.protobuf.FloatValue) +} + +void FloatValue::SharedCtor() { + _is_default_instance_ = false; + _cached_size_ = 0; + value_ = 0; +} + +FloatValue::~FloatValue() { + // @@protoc_insertion_point(destructor:google.protobuf.FloatValue) + SharedDtor(); +} + +void FloatValue::SharedDtor() { + if (this != default_instance_) { + } +} + +void FloatValue::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FloatValue::descriptor() { + protobuf_AssignDescriptorsOnce(); + return FloatValue_descriptor_; +} + +const FloatValue& FloatValue::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto(); + return *default_instance_; +} + +FloatValue* FloatValue::default_instance_ = NULL; + +FloatValue* FloatValue::New(::google::protobuf::Arena* arena) const { + FloatValue* n = new FloatValue; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void FloatValue::Clear() { + value_ = 0; +} + +bool FloatValue::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:google.protobuf.FloatValue) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional float value = 1; + case 1: { + if (tag == 13) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( + input, &value_))); + + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:google.protobuf.FloatValue) + return true; +failure: + // @@protoc_insertion_point(parse_failure:google.protobuf.FloatValue) + return false; +#undef DO_ +} + +void FloatValue::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:google.protobuf.FloatValue) + // optional float value = 1; + if (this->value() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteFloat(1, this->value(), output); + } + + // @@protoc_insertion_point(serialize_end:google.protobuf.FloatValue) +} + +::google::protobuf::uint8* FloatValue::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FloatValue) + // optional float value = 1; + if (this->value() != 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteFloatToArray(1, this->value(), target); + } + + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.FloatValue) + return target; +} + +int FloatValue::ByteSize() const { + int total_size = 0; + + // optional float value = 1; + if (this->value() != 0) { + total_size += 1 + 4; + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FloatValue::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const FloatValue* source = + ::google::protobuf::internal::DynamicCastToGenerated<const FloatValue>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void FloatValue::MergeFrom(const FloatValue& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from.value() != 0) { + set_value(from.value()); + } +} + +void FloatValue::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FloatValue::CopyFrom(const FloatValue& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FloatValue::IsInitialized() const { + + return true; +} + +void FloatValue::Swap(FloatValue* other) { + if (other == this) return; + InternalSwap(other); +} +void FloatValue::InternalSwap(FloatValue* other) { + std::swap(value_, other->value_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata FloatValue::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = FloatValue_descriptor_; + metadata.reflection = FloatValue_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// FloatValue + +// optional float value = 1; +void FloatValue::clear_value() { + value_ = 0; +} + float FloatValue::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.FloatValue.value) + return value_; +} + void FloatValue::set_value(float value) { + + value_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.FloatValue.value) +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// =================================================================== + +#ifndef _MSC_VER +const int Int64Value::kValueFieldNumber; +#endif // !_MSC_VER + +Int64Value::Int64Value() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:google.protobuf.Int64Value) +} + +void Int64Value::InitAsDefaultInstance() { + _is_default_instance_ = true; +} + +Int64Value::Int64Value(const Int64Value& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:google.protobuf.Int64Value) +} + +void Int64Value::SharedCtor() { + _is_default_instance_ = false; + _cached_size_ = 0; + value_ = GOOGLE_LONGLONG(0); +} + +Int64Value::~Int64Value() { + // @@protoc_insertion_point(destructor:google.protobuf.Int64Value) + SharedDtor(); +} + +void Int64Value::SharedDtor() { + if (this != default_instance_) { + } +} + +void Int64Value::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Int64Value::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Int64Value_descriptor_; +} + +const Int64Value& Int64Value::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto(); + return *default_instance_; +} + +Int64Value* Int64Value::default_instance_ = NULL; + +Int64Value* Int64Value::New(::google::protobuf::Arena* arena) const { + Int64Value* n = new Int64Value; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void Int64Value::Clear() { + value_ = GOOGLE_LONGLONG(0); +} + +bool Int64Value::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:google.protobuf.Int64Value) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional int64 value = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>( + input, &value_))); + + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:google.protobuf.Int64Value) + return true; +failure: + // @@protoc_insertion_point(parse_failure:google.protobuf.Int64Value) + return false; +#undef DO_ +} + +void Int64Value::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:google.protobuf.Int64Value) + // optional int64 value = 1; + if (this->value() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteInt64(1, this->value(), output); + } + + // @@protoc_insertion_point(serialize_end:google.protobuf.Int64Value) +} + +::google::protobuf::uint8* Int64Value::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Int64Value) + // optional int64 value = 1; + if (this->value() != 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(1, this->value(), target); + } + + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Int64Value) + return target; +} + +int Int64Value::ByteSize() const { + int total_size = 0; + + // optional int64 value = 1; + if (this->value() != 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int64Size( + this->value()); + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Int64Value::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const Int64Value* source = + ::google::protobuf::internal::DynamicCastToGenerated<const Int64Value>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Int64Value::MergeFrom(const Int64Value& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from.value() != 0) { + set_value(from.value()); + } +} + +void Int64Value::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Int64Value::CopyFrom(const Int64Value& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Int64Value::IsInitialized() const { + + return true; +} + +void Int64Value::Swap(Int64Value* other) { + if (other == this) return; + InternalSwap(other); +} +void Int64Value::InternalSwap(Int64Value* other) { + std::swap(value_, other->value_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata Int64Value::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Int64Value_descriptor_; + metadata.reflection = Int64Value_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// Int64Value + +// optional int64 value = 1; +void Int64Value::clear_value() { + value_ = GOOGLE_LONGLONG(0); +} + ::google::protobuf::int64 Int64Value::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Int64Value.value) + return value_; +} + void Int64Value::set_value(::google::protobuf::int64 value) { + + value_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Int64Value.value) +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// =================================================================== + +#ifndef _MSC_VER +const int UInt64Value::kValueFieldNumber; +#endif // !_MSC_VER + +UInt64Value::UInt64Value() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:google.protobuf.UInt64Value) +} + +void UInt64Value::InitAsDefaultInstance() { + _is_default_instance_ = true; +} + +UInt64Value::UInt64Value(const UInt64Value& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:google.protobuf.UInt64Value) +} + +void UInt64Value::SharedCtor() { + _is_default_instance_ = false; + _cached_size_ = 0; + value_ = GOOGLE_ULONGLONG(0); +} + +UInt64Value::~UInt64Value() { + // @@protoc_insertion_point(destructor:google.protobuf.UInt64Value) + SharedDtor(); +} + +void UInt64Value::SharedDtor() { + if (this != default_instance_) { + } +} + +void UInt64Value::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* UInt64Value::descriptor() { + protobuf_AssignDescriptorsOnce(); + return UInt64Value_descriptor_; +} + +const UInt64Value& UInt64Value::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto(); + return *default_instance_; +} + +UInt64Value* UInt64Value::default_instance_ = NULL; + +UInt64Value* UInt64Value::New(::google::protobuf::Arena* arena) const { + UInt64Value* n = new UInt64Value; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void UInt64Value::Clear() { + value_ = GOOGLE_ULONGLONG(0); +} + +bool UInt64Value::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:google.protobuf.UInt64Value) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional uint64 value = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &value_))); + + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:google.protobuf.UInt64Value) + return true; +failure: + // @@protoc_insertion_point(parse_failure:google.protobuf.UInt64Value) + return false; +#undef DO_ +} + +void UInt64Value::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:google.protobuf.UInt64Value) + // optional uint64 value = 1; + if (this->value() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->value(), output); + } + + // @@protoc_insertion_point(serialize_end:google.protobuf.UInt64Value) +} + +::google::protobuf::uint8* UInt64Value::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UInt64Value) + // optional uint64 value = 1; + if (this->value() != 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(1, this->value(), target); + } + + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.UInt64Value) + return target; +} + +int UInt64Value::ByteSize() const { + int total_size = 0; + + // optional uint64 value = 1; + if (this->value() != 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->value()); + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void UInt64Value::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const UInt64Value* source = + ::google::protobuf::internal::DynamicCastToGenerated<const UInt64Value>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void UInt64Value::MergeFrom(const UInt64Value& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from.value() != 0) { + set_value(from.value()); + } +} + +void UInt64Value::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void UInt64Value::CopyFrom(const UInt64Value& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool UInt64Value::IsInitialized() const { + + return true; +} + +void UInt64Value::Swap(UInt64Value* other) { + if (other == this) return; + InternalSwap(other); +} +void UInt64Value::InternalSwap(UInt64Value* other) { + std::swap(value_, other->value_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata UInt64Value::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = UInt64Value_descriptor_; + metadata.reflection = UInt64Value_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// UInt64Value + +// optional uint64 value = 1; +void UInt64Value::clear_value() { + value_ = GOOGLE_ULONGLONG(0); +} + ::google::protobuf::uint64 UInt64Value::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.UInt64Value.value) + return value_; +} + void UInt64Value::set_value(::google::protobuf::uint64 value) { + + value_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.UInt64Value.value) +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// =================================================================== + +#ifndef _MSC_VER +const int Int32Value::kValueFieldNumber; +#endif // !_MSC_VER + +Int32Value::Int32Value() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:google.protobuf.Int32Value) +} + +void Int32Value::InitAsDefaultInstance() { + _is_default_instance_ = true; +} + +Int32Value::Int32Value(const Int32Value& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:google.protobuf.Int32Value) +} + +void Int32Value::SharedCtor() { + _is_default_instance_ = false; + _cached_size_ = 0; + value_ = 0; +} + +Int32Value::~Int32Value() { + // @@protoc_insertion_point(destructor:google.protobuf.Int32Value) + SharedDtor(); +} + +void Int32Value::SharedDtor() { + if (this != default_instance_) { + } +} + +void Int32Value::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* Int32Value::descriptor() { + protobuf_AssignDescriptorsOnce(); + return Int32Value_descriptor_; +} + +const Int32Value& Int32Value::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto(); + return *default_instance_; +} + +Int32Value* Int32Value::default_instance_ = NULL; + +Int32Value* Int32Value::New(::google::protobuf::Arena* arena) const { + Int32Value* n = new Int32Value; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void Int32Value::Clear() { + value_ = 0; +} + +bool Int32Value::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:google.protobuf.Int32Value) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional int32 value = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( + input, &value_))); + + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:google.protobuf.Int32Value) + return true; +failure: + // @@protoc_insertion_point(parse_failure:google.protobuf.Int32Value) + return false; +#undef DO_ +} + +void Int32Value::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:google.protobuf.Int32Value) + // optional int32 value = 1; + if (this->value() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->value(), output); + } + + // @@protoc_insertion_point(serialize_end:google.protobuf.Int32Value) +} + +::google::protobuf::uint8* Int32Value::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Int32Value) + // optional int32 value = 1; + if (this->value() != 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->value(), target); + } + + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Int32Value) + return target; +} + +int Int32Value::ByteSize() const { + int total_size = 0; + + // optional int32 value = 1; + if (this->value() != 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::Int32Size( + this->value()); + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void Int32Value::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const Int32Value* source = + ::google::protobuf::internal::DynamicCastToGenerated<const Int32Value>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void Int32Value::MergeFrom(const Int32Value& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from.value() != 0) { + set_value(from.value()); + } +} + +void Int32Value::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void Int32Value::CopyFrom(const Int32Value& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool Int32Value::IsInitialized() const { + + return true; +} + +void Int32Value::Swap(Int32Value* other) { + if (other == this) return; + InternalSwap(other); +} +void Int32Value::InternalSwap(Int32Value* other) { + std::swap(value_, other->value_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata Int32Value::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = Int32Value_descriptor_; + metadata.reflection = Int32Value_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// Int32Value + +// optional int32 value = 1; +void Int32Value::clear_value() { + value_ = 0; +} + ::google::protobuf::int32 Int32Value::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Int32Value.value) + return value_; +} + void Int32Value::set_value(::google::protobuf::int32 value) { + + value_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Int32Value.value) +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// =================================================================== + +#ifndef _MSC_VER +const int UInt32Value::kValueFieldNumber; +#endif // !_MSC_VER + +UInt32Value::UInt32Value() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:google.protobuf.UInt32Value) +} + +void UInt32Value::InitAsDefaultInstance() { + _is_default_instance_ = true; +} + +UInt32Value::UInt32Value(const UInt32Value& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:google.protobuf.UInt32Value) +} + +void UInt32Value::SharedCtor() { + _is_default_instance_ = false; + _cached_size_ = 0; + value_ = 0u; +} + +UInt32Value::~UInt32Value() { + // @@protoc_insertion_point(destructor:google.protobuf.UInt32Value) + SharedDtor(); +} + +void UInt32Value::SharedDtor() { + if (this != default_instance_) { + } +} + +void UInt32Value::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* UInt32Value::descriptor() { + protobuf_AssignDescriptorsOnce(); + return UInt32Value_descriptor_; +} + +const UInt32Value& UInt32Value::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto(); + return *default_instance_; +} + +UInt32Value* UInt32Value::default_instance_ = NULL; + +UInt32Value* UInt32Value::New(::google::protobuf::Arena* arena) const { + UInt32Value* n = new UInt32Value; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void UInt32Value::Clear() { + value_ = 0u; +} + +bool UInt32Value::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:google.protobuf.UInt32Value) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional uint32 value = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &value_))); + + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:google.protobuf.UInt32Value) + return true; +failure: + // @@protoc_insertion_point(parse_failure:google.protobuf.UInt32Value) + return false; +#undef DO_ +} + +void UInt32Value::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:google.protobuf.UInt32Value) + // optional uint32 value = 1; + if (this->value() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(1, this->value(), output); + } + + // @@protoc_insertion_point(serialize_end:google.protobuf.UInt32Value) +} + +::google::protobuf::uint8* UInt32Value::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UInt32Value) + // optional uint32 value = 1; + if (this->value() != 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(1, this->value(), target); + } + + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.UInt32Value) + return target; +} + +int UInt32Value::ByteSize() const { + int total_size = 0; + + // optional uint32 value = 1; + if (this->value() != 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->value()); + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void UInt32Value::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const UInt32Value* source = + ::google::protobuf::internal::DynamicCastToGenerated<const UInt32Value>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void UInt32Value::MergeFrom(const UInt32Value& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from.value() != 0) { + set_value(from.value()); + } +} + +void UInt32Value::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void UInt32Value::CopyFrom(const UInt32Value& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool UInt32Value::IsInitialized() const { + + return true; +} + +void UInt32Value::Swap(UInt32Value* other) { + if (other == this) return; + InternalSwap(other); +} +void UInt32Value::InternalSwap(UInt32Value* other) { + std::swap(value_, other->value_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata UInt32Value::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = UInt32Value_descriptor_; + metadata.reflection = UInt32Value_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// UInt32Value + +// optional uint32 value = 1; +void UInt32Value::clear_value() { + value_ = 0u; +} + ::google::protobuf::uint32 UInt32Value::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.UInt32Value.value) + return value_; +} + void UInt32Value::set_value(::google::protobuf::uint32 value) { + + value_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.UInt32Value.value) +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// =================================================================== + +#ifndef _MSC_VER +const int BoolValue::kValueFieldNumber; +#endif // !_MSC_VER + +BoolValue::BoolValue() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:google.protobuf.BoolValue) +} + +void BoolValue::InitAsDefaultInstance() { + _is_default_instance_ = true; +} + +BoolValue::BoolValue(const BoolValue& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:google.protobuf.BoolValue) +} + +void BoolValue::SharedCtor() { + _is_default_instance_ = false; + _cached_size_ = 0; + value_ = false; +} + +BoolValue::~BoolValue() { + // @@protoc_insertion_point(destructor:google.protobuf.BoolValue) + SharedDtor(); +} + +void BoolValue::SharedDtor() { + if (this != default_instance_) { + } +} + +void BoolValue::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* BoolValue::descriptor() { + protobuf_AssignDescriptorsOnce(); + return BoolValue_descriptor_; +} + +const BoolValue& BoolValue::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto(); + return *default_instance_; +} + +BoolValue* BoolValue::default_instance_ = NULL; + +BoolValue* BoolValue::New(::google::protobuf::Arena* arena) const { + BoolValue* n = new BoolValue; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void BoolValue::Clear() { + value_ = false; +} + +bool BoolValue::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:google.protobuf.BoolValue) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional bool value = 1; + case 1: { + if (tag == 8) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( + input, &value_))); + + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:google.protobuf.BoolValue) + return true; +failure: + // @@protoc_insertion_point(parse_failure:google.protobuf.BoolValue) + return false; +#undef DO_ +} + +void BoolValue::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:google.protobuf.BoolValue) + // optional bool value = 1; + if (this->value() != 0) { + ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->value(), output); + } + + // @@protoc_insertion_point(serialize_end:google.protobuf.BoolValue) +} + +::google::protobuf::uint8* BoolValue::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.BoolValue) + // optional bool value = 1; + if (this->value() != 0) { + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(1, this->value(), target); + } + + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.BoolValue) + return target; +} + +int BoolValue::ByteSize() const { + int total_size = 0; + + // optional bool value = 1; + if (this->value() != 0) { + total_size += 1 + 1; + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void BoolValue::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const BoolValue* source = + ::google::protobuf::internal::DynamicCastToGenerated<const BoolValue>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void BoolValue::MergeFrom(const BoolValue& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from.value() != 0) { + set_value(from.value()); + } +} + +void BoolValue::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void BoolValue::CopyFrom(const BoolValue& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool BoolValue::IsInitialized() const { + + return true; +} + +void BoolValue::Swap(BoolValue* other) { + if (other == this) return; + InternalSwap(other); +} +void BoolValue::InternalSwap(BoolValue* other) { + std::swap(value_, other->value_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata BoolValue::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = BoolValue_descriptor_; + metadata.reflection = BoolValue_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// BoolValue + +// optional bool value = 1; +void BoolValue::clear_value() { + value_ = false; +} + bool BoolValue::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.BoolValue.value) + return value_; +} + void BoolValue::set_value(bool value) { + + value_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.BoolValue.value) +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// =================================================================== + +#ifndef _MSC_VER +const int StringValue::kValueFieldNumber; +#endif // !_MSC_VER + +StringValue::StringValue() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:google.protobuf.StringValue) +} + +void StringValue::InitAsDefaultInstance() { + _is_default_instance_ = true; +} + +StringValue::StringValue(const StringValue& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:google.protobuf.StringValue) +} + +void StringValue::SharedCtor() { + _is_default_instance_ = false; + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + +StringValue::~StringValue() { + // @@protoc_insertion_point(destructor:google.protobuf.StringValue) + SharedDtor(); +} + +void StringValue::SharedDtor() { + value_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (this != default_instance_) { + } +} + +void StringValue::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* StringValue::descriptor() { + protobuf_AssignDescriptorsOnce(); + return StringValue_descriptor_; +} + +const StringValue& StringValue::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto(); + return *default_instance_; +} + +StringValue* StringValue::default_instance_ = NULL; + +StringValue* StringValue::New(::google::protobuf::Arena* arena) const { + StringValue* n = new StringValue; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void StringValue::Clear() { + value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + +bool StringValue::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:google.protobuf.StringValue) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string value = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_value())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->value().data(), this->value().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "google.protobuf.StringValue.value"); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:google.protobuf.StringValue) + return true; +failure: + // @@protoc_insertion_point(parse_failure:google.protobuf.StringValue) + return false; +#undef DO_ +} + +void StringValue::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:google.protobuf.StringValue) + // optional string value = 1; + if (this->value().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->value().data(), this->value().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.StringValue.value"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->value(), output); + } + + // @@protoc_insertion_point(serialize_end:google.protobuf.StringValue) +} + +::google::protobuf::uint8* StringValue::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.StringValue) + // optional string value = 1; + if (this->value().size() > 0) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->value().data(), this->value().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.StringValue.value"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->value(), target); + } + + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.StringValue) + return target; +} + +int StringValue::ByteSize() const { + int total_size = 0; + + // optional string value = 1; + if (this->value().size() > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->value()); + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void StringValue::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const StringValue* source = + ::google::protobuf::internal::DynamicCastToGenerated<const StringValue>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void StringValue::MergeFrom(const StringValue& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from.value().size() > 0) { + + value_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.value_); + } +} + +void StringValue::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void StringValue::CopyFrom(const StringValue& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool StringValue::IsInitialized() const { + + return true; +} + +void StringValue::Swap(StringValue* other) { + if (other == this) return; + InternalSwap(other); +} +void StringValue::InternalSwap(StringValue* other) { + value_.Swap(&other->value_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata StringValue::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = StringValue_descriptor_; + metadata.reflection = StringValue_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// StringValue + +// optional string value = 1; +void StringValue::clear_value() { + value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + const ::std::string& StringValue::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.StringValue.value) + return value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void StringValue::set_value(const ::std::string& value) { + + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.StringValue.value) +} + void StringValue::set_value(const char* value) { + + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.StringValue.value) +} + void StringValue::set_value(const char* value, size_t size) { + + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.StringValue.value) +} + ::std::string* StringValue::mutable_value() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.StringValue.value) + return value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* StringValue::release_value() { + + return value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void StringValue::set_allocated_value(::std::string* value) { + if (value != NULL) { + + } else { + + } + value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.StringValue.value) +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// =================================================================== + +#ifndef _MSC_VER +const int BytesValue::kValueFieldNumber; +#endif // !_MSC_VER + +BytesValue::BytesValue() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + SharedCtor(); + // @@protoc_insertion_point(constructor:google.protobuf.BytesValue) +} + +void BytesValue::InitAsDefaultInstance() { + _is_default_instance_ = true; +} + +BytesValue::BytesValue(const BytesValue& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL) { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:google.protobuf.BytesValue) +} + +void BytesValue::SharedCtor() { + _is_default_instance_ = false; + ::google::protobuf::internal::GetEmptyString(); + _cached_size_ = 0; + value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + +BytesValue::~BytesValue() { + // @@protoc_insertion_point(destructor:google.protobuf.BytesValue) + SharedDtor(); +} + +void BytesValue::SharedDtor() { + value_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (this != default_instance_) { + } +} + +void BytesValue::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* BytesValue::descriptor() { + protobuf_AssignDescriptorsOnce(); + return BytesValue_descriptor_; +} + +const BytesValue& BytesValue::default_instance() { + if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto(); + return *default_instance_; +} + +BytesValue* BytesValue::default_instance_ = NULL; + +BytesValue* BytesValue::New(::google::protobuf::Arena* arena) const { + BytesValue* n = new BytesValue; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void BytesValue::Clear() { + value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + +bool BytesValue::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:google.protobuf.BytesValue) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional bytes value = 1; + case 1: { + if (tag == 10) { + DO_(::google::protobuf::internal::WireFormatLite::ReadBytes( + input, this->mutable_value())); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:google.protobuf.BytesValue) + return true; +failure: + // @@protoc_insertion_point(parse_failure:google.protobuf.BytesValue) + return false; +#undef DO_ +} + +void BytesValue::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:google.protobuf.BytesValue) + // optional bytes value = 1; + if (this->value().size() > 0) { + ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased( + 1, this->value(), output); + } + + // @@protoc_insertion_point(serialize_end:google.protobuf.BytesValue) +} + +::google::protobuf::uint8* BytesValue::SerializeWithCachedSizesToArray( + ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.BytesValue) + // optional bytes value = 1; + if (this->value().size() > 0) { + target = + ::google::protobuf::internal::WireFormatLite::WriteBytesToArray( + 1, this->value(), target); + } + + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.BytesValue) + return target; +} + +int BytesValue::ByteSize() const { + int total_size = 0; + + // optional bytes value = 1; + if (this->value().size() > 0) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::BytesSize( + this->value()); + } + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void BytesValue::MergeFrom(const ::google::protobuf::Message& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + const BytesValue* source = + ::google::protobuf::internal::DynamicCastToGenerated<const BytesValue>( + &from); + if (source == NULL) { + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + MergeFrom(*source); + } +} + +void BytesValue::MergeFrom(const BytesValue& from) { + if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (from.value().size() > 0) { + + value_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.value_); + } +} + +void BytesValue::CopyFrom(const ::google::protobuf::Message& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void BytesValue::CopyFrom(const BytesValue& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool BytesValue::IsInitialized() const { + + return true; +} + +void BytesValue::Swap(BytesValue* other) { + if (other == this) return; + InternalSwap(other); +} +void BytesValue::InternalSwap(BytesValue* other) { + value_.Swap(&other->value_); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata BytesValue::GetMetadata() const { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::Metadata metadata; + metadata.descriptor = BytesValue_descriptor_; + metadata.reflection = BytesValue_reflection_; + return metadata; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// BytesValue + +// optional bytes value = 1; +void BytesValue::clear_value() { + value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + const ::std::string& BytesValue::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.BytesValue.value) + return value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void BytesValue::set_value(const ::std::string& value) { + + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.BytesValue.value) +} + void BytesValue::set_value(const char* value) { + + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.BytesValue.value) +} + void BytesValue::set_value(const void* value, size_t size) { + + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.BytesValue.value) +} + ::std::string* BytesValue::mutable_value() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.BytesValue.value) + return value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + ::std::string* BytesValue::release_value() { + + return value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + void BytesValue::set_allocated_value(::std::string* value) { + if (value != NULL) { + + } else { + + } + value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.BytesValue.value) +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// @@protoc_insertion_point(namespace_scope) + +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) diff --git a/src/google/protobuf/wrappers.pb.h b/src/google/protobuf/wrappers.pb.h new file mode 100644 index 00000000..387ebd7c --- /dev/null +++ b/src/google/protobuf/wrappers.pb.h @@ -0,0 +1,1011 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/wrappers.proto + +#ifndef PROTOBUF_google_2fprotobuf_2fwrappers_2eproto__INCLUDED +#define PROTOBUF_google_2fprotobuf_2fwrappers_2eproto__INCLUDED + +#include <string> + +#include <google/protobuf/stubs/common.h> + +#if GOOGLE_PROTOBUF_VERSION < 3000000 +#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 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include <google/protobuf/arena.h> +#include <google/protobuf/arenastring.h> +#include <google/protobuf/generated_message_util.h> +#include <google/protobuf/metadata.h> +#include <google/protobuf/message.h> +#include <google/protobuf/repeated_field.h> +#include <google/protobuf/extension_set.h> +#include <google/protobuf/unknown_field_set.h> +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { + +// Internal implementation detail -- do not call these. +void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto(); +void protobuf_AssignDesc_google_2fprotobuf_2fwrappers_2eproto(); +void protobuf_ShutdownFile_google_2fprotobuf_2fwrappers_2eproto(); + +class DoubleValue; +class FloatValue; +class Int64Value; +class UInt64Value; +class Int32Value; +class UInt32Value; +class BoolValue; +class StringValue; +class BytesValue; + +// =================================================================== + +class LIBPROTOBUF_EXPORT DoubleValue : public ::google::protobuf::Message { + public: + DoubleValue(); + virtual ~DoubleValue(); + + DoubleValue(const DoubleValue& from); + + inline DoubleValue& operator=(const DoubleValue& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const DoubleValue& default_instance(); + + void Swap(DoubleValue* other); + + // implements Message ---------------------------------------------- + + inline DoubleValue* New() const { return New(NULL); } + + DoubleValue* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const DoubleValue& from); + void MergeFrom(const DoubleValue& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(DoubleValue* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional double value = 1; + void clear_value(); + static const int kValueFieldNumber = 1; + double value() const; + void set_value(double value); + + // @@protoc_insertion_point(class_scope:google.protobuf.DoubleValue) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + double value_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fwrappers_2eproto(); + + void InitAsDefaultInstance(); + static DoubleValue* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT FloatValue : public ::google::protobuf::Message { + public: + FloatValue(); + virtual ~FloatValue(); + + FloatValue(const FloatValue& from); + + inline FloatValue& operator=(const FloatValue& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FloatValue& default_instance(); + + void Swap(FloatValue* other); + + // implements Message ---------------------------------------------- + + inline FloatValue* New() const { return New(NULL); } + + FloatValue* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const FloatValue& from); + void MergeFrom(const FloatValue& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(FloatValue* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional float value = 1; + void clear_value(); + static const int kValueFieldNumber = 1; + float value() const; + void set_value(float value); + + // @@protoc_insertion_point(class_scope:google.protobuf.FloatValue) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + float value_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fwrappers_2eproto(); + + void InitAsDefaultInstance(); + static FloatValue* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT Int64Value : public ::google::protobuf::Message { + public: + Int64Value(); + virtual ~Int64Value(); + + Int64Value(const Int64Value& from); + + inline Int64Value& operator=(const Int64Value& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Int64Value& default_instance(); + + void Swap(Int64Value* other); + + // implements Message ---------------------------------------------- + + inline Int64Value* New() const { return New(NULL); } + + Int64Value* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Int64Value& from); + void MergeFrom(const Int64Value& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Int64Value* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional int64 value = 1; + void clear_value(); + static const int kValueFieldNumber = 1; + ::google::protobuf::int64 value() const; + void set_value(::google::protobuf::int64 value); + + // @@protoc_insertion_point(class_scope:google.protobuf.Int64Value) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::int64 value_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fwrappers_2eproto(); + + void InitAsDefaultInstance(); + static Int64Value* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT UInt64Value : public ::google::protobuf::Message { + public: + UInt64Value(); + virtual ~UInt64Value(); + + UInt64Value(const UInt64Value& from); + + inline UInt64Value& operator=(const UInt64Value& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const UInt64Value& default_instance(); + + void Swap(UInt64Value* other); + + // implements Message ---------------------------------------------- + + inline UInt64Value* New() const { return New(NULL); } + + UInt64Value* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const UInt64Value& from); + void MergeFrom(const UInt64Value& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(UInt64Value* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional uint64 value = 1; + void clear_value(); + static const int kValueFieldNumber = 1; + ::google::protobuf::uint64 value() const; + void set_value(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:google.protobuf.UInt64Value) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::uint64 value_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fwrappers_2eproto(); + + void InitAsDefaultInstance(); + static UInt64Value* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT Int32Value : public ::google::protobuf::Message { + public: + Int32Value(); + virtual ~Int32Value(); + + Int32Value(const Int32Value& from); + + inline Int32Value& operator=(const Int32Value& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const Int32Value& default_instance(); + + void Swap(Int32Value* other); + + // implements Message ---------------------------------------------- + + inline Int32Value* New() const { return New(NULL); } + + Int32Value* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const Int32Value& from); + void MergeFrom(const Int32Value& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(Int32Value* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional int32 value = 1; + void clear_value(); + static const int kValueFieldNumber = 1; + ::google::protobuf::int32 value() const; + void set_value(::google::protobuf::int32 value); + + // @@protoc_insertion_point(class_scope:google.protobuf.Int32Value) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::int32 value_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fwrappers_2eproto(); + + void InitAsDefaultInstance(); + static Int32Value* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT UInt32Value : public ::google::protobuf::Message { + public: + UInt32Value(); + virtual ~UInt32Value(); + + UInt32Value(const UInt32Value& from); + + inline UInt32Value& operator=(const UInt32Value& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const UInt32Value& default_instance(); + + void Swap(UInt32Value* other); + + // implements Message ---------------------------------------------- + + inline UInt32Value* New() const { return New(NULL); } + + UInt32Value* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const UInt32Value& from); + void MergeFrom(const UInt32Value& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(UInt32Value* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional uint32 value = 1; + void clear_value(); + static const int kValueFieldNumber = 1; + ::google::protobuf::uint32 value() const; + void set_value(::google::protobuf::uint32 value); + + // @@protoc_insertion_point(class_scope:google.protobuf.UInt32Value) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::uint32 value_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fwrappers_2eproto(); + + void InitAsDefaultInstance(); + static UInt32Value* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT BoolValue : public ::google::protobuf::Message { + public: + BoolValue(); + virtual ~BoolValue(); + + BoolValue(const BoolValue& from); + + inline BoolValue& operator=(const BoolValue& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const BoolValue& default_instance(); + + void Swap(BoolValue* other); + + // implements Message ---------------------------------------------- + + inline BoolValue* New() const { return New(NULL); } + + BoolValue* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const BoolValue& from); + void MergeFrom(const BoolValue& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(BoolValue* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional bool value = 1; + void clear_value(); + static const int kValueFieldNumber = 1; + bool value() const; + void set_value(bool value); + + // @@protoc_insertion_point(class_scope:google.protobuf.BoolValue) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + bool value_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fwrappers_2eproto(); + + void InitAsDefaultInstance(); + static BoolValue* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT StringValue : public ::google::protobuf::Message { + public: + StringValue(); + virtual ~StringValue(); + + StringValue(const StringValue& from); + + inline StringValue& operator=(const StringValue& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const StringValue& default_instance(); + + void Swap(StringValue* other); + + // implements Message ---------------------------------------------- + + inline StringValue* New() const { return New(NULL); } + + StringValue* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const StringValue& from); + void MergeFrom(const StringValue& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(StringValue* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string value = 1; + void clear_value(); + static const int kValueFieldNumber = 1; + const ::std::string& value() const; + void set_value(const ::std::string& value); + void set_value(const char* value); + void set_value(const char* value, size_t size); + ::std::string* mutable_value(); + ::std::string* release_value(); + void set_allocated_value(::std::string* value); + + // @@protoc_insertion_point(class_scope:google.protobuf.StringValue) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr value_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fwrappers_2eproto(); + + void InitAsDefaultInstance(); + static StringValue* default_instance_; +}; +// ------------------------------------------------------------------- + +class LIBPROTOBUF_EXPORT BytesValue : public ::google::protobuf::Message { + public: + BytesValue(); + virtual ~BytesValue(); + + BytesValue(const BytesValue& from); + + inline BytesValue& operator=(const BytesValue& from) { + CopyFrom(from); + return *this; + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const BytesValue& default_instance(); + + void Swap(BytesValue* other); + + // implements Message ---------------------------------------------- + + inline BytesValue* New() const { return New(NULL); } + + BytesValue* New(::google::protobuf::Arena* arena) const; + void CopyFrom(const ::google::protobuf::Message& from); + void MergeFrom(const ::google::protobuf::Message& from); + void CopyFrom(const BytesValue& from); + void MergeFrom(const BytesValue& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(BytesValue* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return _internal_metadata_.arena(); + } + inline void* MaybeArenaPtr() const { + return _internal_metadata_.raw_arena_ptr(); + } + public: + + ::google::protobuf::Metadata GetMetadata() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional bytes value = 1; + void clear_value(); + static const int kValueFieldNumber = 1; + const ::std::string& value() const; + void set_value(const ::std::string& value); + void set_value(const char* value); + void set_value(const void* value, size_t size); + ::std::string* mutable_value(); + ::std::string* release_value(); + void set_allocated_value(::std::string* value); + + // @@protoc_insertion_point(class_scope:google.protobuf.BytesValue) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + bool _is_default_instance_; + ::google::protobuf::internal::ArenaStringPtr value_; + mutable int _cached_size_; + friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_AssignDesc_google_2fprotobuf_2fwrappers_2eproto(); + friend void protobuf_ShutdownFile_google_2fprotobuf_2fwrappers_2eproto(); + + void InitAsDefaultInstance(); + static BytesValue* default_instance_; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// DoubleValue + +// optional double value = 1; +inline void DoubleValue::clear_value() { + value_ = 0; +} +inline double DoubleValue::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.DoubleValue.value) + return value_; +} +inline void DoubleValue::set_value(double value) { + + value_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.DoubleValue.value) +} + +// ------------------------------------------------------------------- + +// FloatValue + +// optional float value = 1; +inline void FloatValue::clear_value() { + value_ = 0; +} +inline float FloatValue::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.FloatValue.value) + return value_; +} +inline void FloatValue::set_value(float value) { + + value_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.FloatValue.value) +} + +// ------------------------------------------------------------------- + +// Int64Value + +// optional int64 value = 1; +inline void Int64Value::clear_value() { + value_ = GOOGLE_LONGLONG(0); +} +inline ::google::protobuf::int64 Int64Value::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Int64Value.value) + return value_; +} +inline void Int64Value::set_value(::google::protobuf::int64 value) { + + value_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Int64Value.value) +} + +// ------------------------------------------------------------------- + +// UInt64Value + +// optional uint64 value = 1; +inline void UInt64Value::clear_value() { + value_ = GOOGLE_ULONGLONG(0); +} +inline ::google::protobuf::uint64 UInt64Value::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.UInt64Value.value) + return value_; +} +inline void UInt64Value::set_value(::google::protobuf::uint64 value) { + + value_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.UInt64Value.value) +} + +// ------------------------------------------------------------------- + +// Int32Value + +// optional int32 value = 1; +inline void Int32Value::clear_value() { + value_ = 0; +} +inline ::google::protobuf::int32 Int32Value::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.Int32Value.value) + return value_; +} +inline void Int32Value::set_value(::google::protobuf::int32 value) { + + value_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.Int32Value.value) +} + +// ------------------------------------------------------------------- + +// UInt32Value + +// optional uint32 value = 1; +inline void UInt32Value::clear_value() { + value_ = 0u; +} +inline ::google::protobuf::uint32 UInt32Value::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.UInt32Value.value) + return value_; +} +inline void UInt32Value::set_value(::google::protobuf::uint32 value) { + + value_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.UInt32Value.value) +} + +// ------------------------------------------------------------------- + +// BoolValue + +// optional bool value = 1; +inline void BoolValue::clear_value() { + value_ = false; +} +inline bool BoolValue::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.BoolValue.value) + return value_; +} +inline void BoolValue::set_value(bool value) { + + value_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.BoolValue.value) +} + +// ------------------------------------------------------------------- + +// StringValue + +// optional string value = 1; +inline void StringValue::clear_value() { + value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& StringValue::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.StringValue.value) + return value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void StringValue::set_value(const ::std::string& value) { + + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.StringValue.value) +} +inline void StringValue::set_value(const char* value) { + + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.StringValue.value) +} +inline void StringValue::set_value(const char* value, size_t size) { + + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.StringValue.value) +} +inline ::std::string* StringValue::mutable_value() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.StringValue.value) + return value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* StringValue::release_value() { + + return value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void StringValue::set_allocated_value(::std::string* value) { + if (value != NULL) { + + } else { + + } + value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.StringValue.value) +} + +// ------------------------------------------------------------------- + +// BytesValue + +// optional bytes value = 1; +inline void BytesValue::clear_value() { + value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline const ::std::string& BytesValue::value() const { + // @@protoc_insertion_point(field_get:google.protobuf.BytesValue.value) + return value_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void BytesValue::set_value(const ::std::string& value) { + + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.BytesValue.value) +} +inline void BytesValue::set_value(const char* value) { + + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.BytesValue.value) +} +inline void BytesValue::set_value(const void* value, size_t size) { + + value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast<const char*>(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.BytesValue.value) +} +inline ::std::string* BytesValue::mutable_value() { + + // @@protoc_insertion_point(field_mutable:google.protobuf.BytesValue.value) + return value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* BytesValue::release_value() { + + return value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void BytesValue::set_allocated_value(::std::string* value) { + if (value != NULL) { + + } else { + + } + value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.BytesValue.value) +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + + +// @@protoc_insertion_point(namespace_scope) + +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_google_2fprotobuf_2fwrappers_2eproto__INCLUDED diff --git a/src/google/protobuf/wrappers.proto b/src/google/protobuf/wrappers.proto index 5164c24c..a13e6edb 100644 --- a/src/google/protobuf/wrappers.proto +++ b/src/google/protobuf/wrappers.proto @@ -40,6 +40,8 @@ package google.protobuf; option java_multiple_files = true; option java_outer_classname = "WrappersProto"; option java_package = "com.google.protobuf"; +option csharp_namespace = "Google.ProtocolBuffers"; +option objc_class_prefix = "GPB"; // Wrapper message for double. |