aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2016-03-26 01:24:11 +0100
committerShauren <shauren.trinity@gmail.com>2016-03-26 01:24:11 +0100
commit499a15993293bf3a793690bd8fe75a2459febb73 (patch)
tree5e53f24f98fb04ea808bee5c0fd0a686919cae49
parent092d52080f3c8378bc3e5f35b7066c03500314e2 (diff)
Contrib: Added sources of the protoc plugin used to generate services
-rw-r--r--contrib/protoc-bnet/BnetCodeGenerator.cpp68
-rw-r--r--contrib/protoc-bnet/BnetCodeGenerator.h24
-rw-r--r--contrib/protoc-bnet/BnetFileGenerator.cpp692
-rw-r--r--contrib/protoc-bnet/BnetFileGenerator.h109
-rw-r--r--contrib/protoc-bnet/BnetServiceGenerator.cpp312
-rw-r--r--contrib/protoc-bnet/BnetServiceGenerator.h86
-rw-r--r--contrib/protoc-bnet/CMakeLists.txt32
-rw-r--r--contrib/protoc-bnet/config.h31
-rw-r--r--contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_enum.cc288
-rw-r--r--contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_enum.h103
-rw-r--r--contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_enum_field.cc431
-rw-r--r--contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_enum_field.h122
-rw-r--r--contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_extension.cc210
-rw-r--r--contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_extension.h86
-rw-r--r--contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_field.cc166
-rw-r--r--contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_field.h185
-rw-r--r--contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_helpers.cc494
-rw-r--r--contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_helpers.h206
-rw-r--r--contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_message.cc2645
-rw-r--r--contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_message.h175
-rw-r--r--contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_message_field.cc375
-rw-r--r--contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_message_field.h121
-rw-r--r--contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_options.h58
-rw-r--r--contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_primitive_field.cc451
-rw-r--r--contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_primitive_field.h123
-rw-r--r--contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_string_field.cc642
-rw-r--r--contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_string_field.h127
-rw-r--r--contrib/protoc-bnet/google/protobuf/stubs/hash.h232
-rw-r--r--contrib/protoc-bnet/google/protobuf/stubs/strutil.cc1279
-rw-r--r--contrib/protoc-bnet/google/protobuf/stubs/strutil.h562
-rw-r--r--contrib/protoc-bnet/google/protobuf/stubs/substitute.cc134
-rw-r--r--contrib/protoc-bnet/google/protobuf/stubs/substitute.h170
-rw-r--r--contrib/protoc-bnet/main.cpp8
-rw-r--r--contrib/protoc-bnet/method_options.pb.cc86
-rw-r--r--contrib/protoc-bnet/method_options.pb.h64
-rw-r--r--contrib/protoc-bnet/service_options.pb.cc95
-rw-r--r--contrib/protoc-bnet/service_options.pb.h68
37 files changed, 11060 insertions, 0 deletions
diff --git a/contrib/protoc-bnet/BnetCodeGenerator.cpp b/contrib/protoc-bnet/BnetCodeGenerator.cpp
new file mode 100644
index 00000000000..f3627192755
--- /dev/null
+++ b/contrib/protoc-bnet/BnetCodeGenerator.cpp
@@ -0,0 +1,68 @@
+//
+// Created by tea on 10.03.16.
+//
+
+#include <vector>
+#include "BnetFileGenerator.h"
+#include "google/protobuf/compiler/cpp/cpp_helpers.h"
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/descriptor.pb.h>
+
+#include "BnetCodeGenerator.h"
+
+bool BnetCodeGenerator::Generate(pb::FileDescriptor const* file, std::string const& parameter,
+ pbc::GeneratorContext* generator_context, std::string* error) const
+{
+ std::vector<std::pair<std::string, std::string>> options;
+ google::protobuf::compiler::ParseGeneratorParameter(parameter, &options);
+
+ // -----------------------------------------------------------------
+ // parse generator options
+
+ google::protobuf::compiler::cpp::Options file_options;
+
+ for (int i = 0; i < options.size(); i++)
+ {
+ if (options[i].first == "dllexport_decl")
+ {
+ file_options.dllexport_decl = options[i].second;
+ }
+ else if (options[i].first == "safe_boundary_check")
+ {
+ file_options.safe_boundary_check = true;
+ }
+ else
+ {
+ *error = "Unknown generator option: " + options[i].first;
+ return false;
+ }
+ }
+
+ // -----------------------------------------------------------------
+
+
+ std::string basename = google::protobuf::compiler::cpp::StripProto(file->name());
+ basename.append(".pb");
+
+ BnetFileGenerator file_generator(file, file_options);
+
+ // Generate header.
+ {
+ pb::scoped_ptr <google::protobuf::io::ZeroCopyOutputStream> output(
+ generator_context->Open(basename + ".h"));
+ google::protobuf::io::Printer printer(output.get(), '$');
+ file_generator.GenerateHeader(&printer);
+ }
+
+ // Generate cc file.
+ {
+ pb::scoped_ptr <google::protobuf::io::ZeroCopyOutputStream> output(
+ generator_context->Open(basename + ".cc"));
+ google::protobuf::io::Printer printer(output.get(), '$');
+ file_generator.GenerateSource(&printer);
+ }
+
+ return true;
+}
+
diff --git a/contrib/protoc-bnet/BnetCodeGenerator.h b/contrib/protoc-bnet/BnetCodeGenerator.h
new file mode 100644
index 00000000000..1d40ae2522e
--- /dev/null
+++ b/contrib/protoc-bnet/BnetCodeGenerator.h
@@ -0,0 +1,24 @@
+//
+// Created by tea on 10.03.16.
+//
+
+#ifndef PROTOC_BNET_BNETCODEGENERATOR_H
+#define PROTOC_BNET_BNETCODEGENERATOR_H
+
+#include <google/protobuf/compiler/code_generator.h>
+#include <string>
+
+namespace pb = google::protobuf;
+namespace pbc = pb::compiler;
+
+class BnetCodeGenerator : public pbc::CodeGenerator
+{
+public:
+ bool Generate(pb::FileDescriptor const* file,
+ std::string const& parameter,
+ pbc::GeneratorContext* generator_context,
+ std::string* error) const override;
+
+};
+
+#endif //PROTOC_BNET_BNETCODEGENERATOR_H
diff --git a/contrib/protoc-bnet/BnetFileGenerator.cpp b/contrib/protoc-bnet/BnetFileGenerator.cpp
new file mode 100644
index 00000000000..92f836fad31
--- /dev/null
+++ b/contrib/protoc-bnet/BnetFileGenerator.cpp
@@ -0,0 +1,692 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 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 "BnetFileGenerator.h"
+#include <memory>
+#include <set>
+
+#include "google/protobuf/compiler/cpp/cpp_enum.h"
+#include "BnetServiceGenerator.h"
+#include "BnetCodeGenerator.h"
+#include "google/protobuf/compiler/cpp/cpp_extension.h"
+#include "google/protobuf/compiler/cpp/cpp_helpers.h"
+#include "google/protobuf/compiler/cpp/cpp_message.h"
+#include "google/protobuf/compiler/cpp/cpp_field.h"
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/descriptor.pb.h>
+#include "google/protobuf/stubs/strutil.h"
+
+
+// ===================================================================
+
+BnetFileGenerator::BnetFileGenerator(const pb::FileDescriptor* file, const pbcpp::Options& options)
+ : file_(file),
+ message_generators_(
+ new pb::scoped_ptr<pbcpp::MessageGenerator>[file->message_type_count()]),
+ enum_generators_(
+ new pb::scoped_ptr<pbcpp::EnumGenerator>[file->enum_type_count()]),
+ service_generators_(
+ new pb::scoped_ptr<BnetServiceGenerator>[file->service_count()]),
+ extension_generators_(
+ new pb::scoped_ptr<pbcpp::ExtensionGenerator>[file->extension_count()]),
+ options_(options)
+{
+
+ for (int i = 0; i < file->message_type_count(); i++)
+ {
+ message_generators_[i].reset(
+ new pbcpp::MessageGenerator(file->message_type(i), options));
+ }
+
+ for (int i = 0; i < file->enum_type_count(); i++)
+ {
+ enum_generators_[i].reset(
+ new pbcpp::EnumGenerator(file->enum_type(i), options));
+ }
+
+ for (int i = 0; i < file->service_count(); i++)
+ {
+ service_generators_[i].reset(
+ new BnetServiceGenerator(file->service(i), options));
+ }
+
+ for (int i = 0; i < file->extension_count(); i++)
+ {
+ extension_generators_[i].reset(
+ new pbcpp::ExtensionGenerator(file->extension(i), options));
+ }
+
+ pb::SplitStringUsing(file_->package(), ".", &package_parts_);
+}
+
+BnetFileGenerator::~BnetFileGenerator() { }
+
+void BnetFileGenerator::GenerateHeader(pb::io::Printer* printer)
+{
+ std::string filename_identifier = pbcpp::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",
+ pb::SimpleItoa(pb::internal::kMinHeaderVersionForProtoc),
+ "protoc_version", pb::SimpleItoa(GOOGLE_PROTOBUF_VERSION));
+
+ // OK, it's now safe to #include other files.
+ printer->Print("#include <google/protobuf/generated_message_util.h>\n");
+ if (file_->message_type_count() > 0)
+ {
+ if (pbcpp::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 (pbcpp::HasDescriptorMethods(file_) && pbcpp::HasEnumDefinitions(file_))
+ printer->Print("#include <google/protobuf/generated_enum_reflection.h>\n");
+
+ if (pbcpp::UseUnknownFieldSet(file_) && file_->message_type_count() > 0)
+ {
+ printer->Print("#include <google/protobuf/unknown_field_set.h>\n");
+ }
+
+ std::set<std::string> public_import_names;
+ for (int i = 0; i < file_->public_dependency_count(); i++)
+ public_import_names.insert(file_->public_dependency(i)->name());
+
+ for (int i = 0; i < file_->dependency_count(); i++)
+ {
+ const std::string& name = file_->dependency(i)->name();
+ bool public_import = (public_import_names.count(name) != 0);
+
+ printer->Print(
+ "#include \"$dependency$.pb.h\"$iwyu$\n",
+ "dependency", pbcpp::StripProto(name),
+ "iwyu", (public_import) ? " // IWYU pragma: export" : "");
+ }
+
+ if (file_->service_count() > 0)
+ {
+ printer->Print("#include \"ServiceBase.h\"\n");
+ printer->Print("#include \"MessageBuffer.h\"\n");
+ printer->Print("#include <functional>\n");
+ printer->Print("#include <type_traits>\n");
+ }
+
+ printer->Print("// @@protoc_insertion_point(includes)\n");
+
+ // 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", pbcpp::GlobalAddDescriptorsName(file_->name()),
+ "dllexport_decl", 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", pbcpp::GlobalAssignDescriptorsName(file_->name()),
+ "shutdownfilename", pbcpp::GlobalShutdownFileName(file_->name()));
+
+ // Generate forward declarations of classes.
+ for (int i = 0; i < file_->message_type_count(); i++)
+ message_generators_[i]->GenerateForwardDeclaration(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);
+
+ printer->Print(pbcpp::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(pbcpp::kThinSeparator);
+ printer->Print("\n");
+ }
+ message_generators_[i]->GenerateClassDefinition(printer);
+ }
+
+ printer->Print("\n");
+ printer->Print(pbcpp::kThickSeparator);
+ printer->Print("\n");
+
+ // Generate service definitions.
+ for (int i = 0; i < file_->service_count(); i++)
+ {
+ if (i > 0)
+ {
+ printer->Print("\n");
+ printer->Print(pbcpp::kThinSeparator);
+ printer->Print("\n");
+ }
+ service_generators_[i]->GenerateDeclarations(printer);
+ }
+
+ printer->Print("\n");
+ printer->Print(pbcpp::kThickSeparator);
+ printer->Print("\n");
+
+ // Declare extension identifiers.
+ for (int i = 0; i < file_->extension_count(); i++)
+ {
+ extension_generators_[i]->GenerateDeclaration(printer);
+ }
+
+ printer->Print("\n");
+ printer->Print(pbcpp::kThickSeparator);
+ printer->Print("\n");
+
+
+ // Generate class inline methods.
+ for (int i = 0; i < file_->message_type_count(); i++)
+ {
+ if (i > 0)
+ {
+ printer->Print(pbcpp::kThinSeparator);
+ printer->Print("\n");
+ }
+ message_generators_[i]->GenerateInlineMethods(printer);
+ }
+
+ printer->Print(
+ "\n"
+ "// @@protoc_insertion_point(namespace_scope)\n");
+
+ // Close up namespace.
+ GenerateNamespaceClosers(printer);
+
+ // Emit GetEnumDescriptor specializations into google::protobuf namespace:
+ if (pbcpp::HasDescriptorMethods(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 google\n} // namespace protobuf\n"
+ "#endif // SWIG\n");
+ }
+
+ printer->Print(
+ "\n"
+ "// @@protoc_insertion_point(global_scope)\n"
+ "\n");
+
+ printer->Print(
+ "#endif // PROTOBUF_$filename_identifier$__INCLUDED\n",
+ "filename_identifier", filename_identifier);
+}
+
+void BnetFileGenerator::GenerateSource(pb::io::Printer* printer)
+{
+ printer->Print(
+ "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
+ "// source: $filename$\n"
+ "\n"
+
+ // The generated code calls accessors that might be deprecated. We don't
+ // want the compiler to warn in generated code.
+ "#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION\n"
+ "#include \"$basename$.pb.h\"\n"
+ "\n"
+ "#include <algorithm>\n" // for swap()
+ "#include <utility>\n" // for move()
+ "\n"
+ "#include <google/protobuf/stubs/common.h>\n"
+ "#include <google/protobuf/stubs/once.h>\n"
+ "#include <google/protobuf/io/coded_stream.h>\n"
+ "#include <google/protobuf/wire_format_lite_inl.h>\n",
+ "filename", file_->name(),
+ "basename", pbcpp::StripProto(file_->name()));
+
+ // Unknown fields implementation in lite mode uses StringOutputStream
+ if (!pbcpp::UseUnknownFieldSet(file_) && file_->message_type_count() > 0)
+ {
+ printer->Print(
+ "#include <google/protobuf/io/zero_copy_stream_impl_lite.h>\n");
+ }
+
+ if (pbcpp::HasDescriptorMethods(file_))
+ {
+ printer->Print(
+ "#include <google/protobuf/descriptor.h>\n"
+ "#include <google/protobuf/generated_message_reflection.h>\n"
+ "#include <google/protobuf/reflection_ops.h>\n"
+ "#include <google/protobuf/wire_format.h>\n");
+ }
+
+ printer->Print("#include \"Log.h\"\n");
+
+ if (file_->service_count() > 0)
+ printer->Print("#include \"BattlenetRpcErrorCodes.h\"\n");
+
+ printer->Print(
+ "// @@protoc_insertion_point(includes)\n");
+
+ GenerateNamespaceOpeners(printer);
+
+ if (pbcpp::HasDescriptorMethods(file_))
+ {
+ printer->Print(
+ "\n"
+ "namespace {\n"
+ "\n");
+ for (int i = 0; i < file_->message_type_count(); i++)
+ {
+ message_generators_[i]->GenerateDescriptorDeclarations(printer);
+ }
+ for (int i = 0; i < file_->enum_type_count(); i++)
+ {
+ printer->Print(
+ "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n",
+ "name", pbcpp::ClassName(file_->enum_type(i), false));
+ }
+
+ for (int i = 0; i < file_->service_count(); i++)
+ {
+ printer->Print(
+ "const ::google::protobuf::ServiceDescriptor* $name$_descriptor_ = NULL;\n",
+ "name", file_->service(i)->name());
+ }
+
+ printer->Print(
+ "\n"
+ "} // namespace\n"
+ "\n");
+ }
+
+ // Define our externally-visible BuildDescriptors() function. (For the lite
+ // library, all this does is initialize default instances.)
+ GenerateBuildDescriptors(printer);
+
+ // Generate enums.
+ for (int i = 0; i < file_->enum_type_count(); i++)
+ {
+ enum_generators_[i]->GenerateMethods(printer);
+ }
+
+ // Generate classes.
+ for (int i = 0; i < file_->message_type_count(); i++)
+ {
+ printer->Print("\n");
+ printer->Print(pbcpp::kThickSeparator);
+ printer->Print("\n");
+ message_generators_[i]->GenerateClassMethods(printer);
+ }
+
+ // Generate services.
+ for (int i = 0; i < file_->service_count(); i++)
+ {
+ if (i == 0)
+ printer->Print("\n");
+ printer->Print(pbcpp::kThickSeparator);
+ printer->Print("\n");
+ service_generators_[i]->GenerateImplementation(printer);
+ }
+
+ // Define extensions.
+ for (int i = 0; i < file_->extension_count(); i++)
+ {
+ extension_generators_[i]->GenerateDefinition(printer);
+ }
+
+ printer->Print(
+ "\n"
+ "// @@protoc_insertion_point(namespace_scope)\n");
+
+ GenerateNamespaceClosers(printer);
+
+ printer->Print(
+ "\n"
+ "// @@protoc_insertion_point(global_scope)\n");
+}
+
+void BnetFileGenerator::GenerateBuildDescriptors(pb::io::Printer* printer)
+{
+ // AddDescriptors() is a file-level procedure which adds the encoded
+ // FileDescriptorProto for this .proto file to the global DescriptorPool for
+ // generated files (DescriptorPool::generated_pool()). It either runs at
+ // static initialization time (by default) or when default_instance() is
+ // called for the first time (in LITE_RUNTIME mode with
+ // GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER flag enabled). This procedure also
+ // constructs default instances and registers extensions.
+ //
+ // Its sibling, AssignDescriptors(), actually pulls the compiled
+ // FileDescriptor from the DescriptorPool and uses it to populate all of
+ // the global variables which store pointers to the descriptor objects.
+ // It also constructs the reflection objects. It is called the first time
+ // anyone calls descriptor() or GetReflection() on one of the types defined
+ // in the file.
+
+ // In optimize_for = LITE_RUNTIME mode, we don't generate AssignDescriptors()
+ // and we only use AddDescriptors() to allocate default instances.
+ if (pbcpp::HasDescriptorMethods(file_))
+ {
+ printer->Print(
+ "\n"
+ "void $assigndescriptorsname$() {\n",
+ "assigndescriptorsname", pbcpp::GlobalAssignDescriptorsName(file_->name()));
+ printer->Indent();
+
+ // Make sure the file has found its way into the pool. If a descriptor
+ // is requested *during* static init then AddDescriptors() may not have
+ // been called yet, so we call it manually. Note that it's fine if
+ // AddDescriptors() is called multiple times.
+ printer->Print(
+ "$adddescriptorsname$();\n",
+ "adddescriptorsname", pbcpp::GlobalAddDescriptorsName(file_->name()));
+
+ // Get the file's descriptor from the pool.
+ printer->Print(
+ "const ::google::protobuf::FileDescriptor* file =\n"
+ " ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(\n"
+ " \"$filename$\");\n"
+ // Note that this GOOGLE_CHECK is necessary to prevent a warning about "file"
+ // being unused when compiling an empty .proto file.
+ "GOOGLE_CHECK(file != NULL);\n",
+ "filename", file_->name());
+
+ // Go through all the stuff defined in this file and generated code to
+ // assign the global descriptor pointers based on the file descriptor.
+ for (int i = 0; i < file_->message_type_count(); i++)
+ {
+ message_generators_[i]->GenerateDescriptorInitializer(printer, i);
+ }
+ for (int i = 0; i < file_->enum_type_count(); i++)
+ {
+ enum_generators_[i]->GenerateDescriptorInitializer(printer, i);
+ }
+ for (int i = 0; i < file_->service_count(); i++)
+ {
+ service_generators_[i]->GenerateDescriptorInitializer(printer, i);
+ }
+
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "\n");
+
+ // ---------------------------------------------------------------
+
+ // protobuf_AssignDescriptorsOnce(): The first time it is called, calls
+ // AssignDescriptors(). All later times, waits for the first call to
+ // complete and then returns.
+ printer->Print(
+ "namespace {\n"
+ "\n"
+ "GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);\n"
+ "inline void protobuf_AssignDescriptorsOnce() {\n"
+ " ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,\n"
+ " &$assigndescriptorsname$);\n"
+ "}\n"
+ "\n",
+ "assigndescriptorsname", pbcpp::GlobalAssignDescriptorsName(file_->name()));
+
+ // protobuf_RegisterTypes(): Calls
+ // MessageFactory::InternalRegisterGeneratedType() for each message type.
+ printer->Print(
+ "void protobuf_RegisterTypes(const ::std::string&) {\n"
+ " protobuf_AssignDescriptorsOnce();\n");
+ printer->Indent();
+
+ for (int i = 0; i < file_->message_type_count(); i++)
+ {
+ message_generators_[i]->GenerateTypeRegistrations(printer);
+ }
+
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "\n"
+ "} // namespace\n");
+ }
+
+ // -----------------------------------------------------------------
+
+ // ShutdownFile(): Deletes descriptors, default instances, etc. on shutdown.
+ printer->Print(
+ "\n"
+ "void $shutdownfilename$() {\n",
+ "shutdownfilename", pbcpp::GlobalShutdownFileName(file_->name()));
+ printer->Indent();
+
+ for (int i = 0; i < file_->message_type_count(); i++)
+ {
+ message_generators_[i]->GenerateShutdownCode(printer);
+ }
+
+ printer->Outdent();
+ printer->Print(
+ "}\n\n");
+
+ // -----------------------------------------------------------------
+
+ // Now generate the AddDescriptors() function.
+ pbcpp::PrintHandlingOptionalStaticInitializers(
+ file_, printer,
+ // With static initializers.
+ // Note that we don't need any special synchronization in the following code
+ // because it is called at static init time before any threads exist.
+ "void $adddescriptorsname$() {\n"
+ " static bool already_here = false;\n"
+ " if (already_here) return;\n"
+ " already_here = true;\n"
+ " GOOGLE_PROTOBUF_VERIFY_VERSION;\n"
+ "\n",
+ // Without.
+ "void $adddescriptorsname$_impl() {\n"
+ " GOOGLE_PROTOBUF_VERIFY_VERSION;\n"
+ "\n",
+ // Vars.
+ "adddescriptorsname", pbcpp::GlobalAddDescriptorsName(file_->name()));
+
+ printer->Indent();
+
+ // Call the AddDescriptors() methods for all of our dependencies, to make
+ // sure they get added first.
+ for (int i = 0; i < file_->dependency_count(); i++)
+ {
+ const pb::FileDescriptor* dependency = file_->dependency(i);
+ // Print the namespace prefix for the dependency.
+ std::string add_desc_name = pbcpp::QualifiedFileLevelSymbol(
+ dependency->package(), pbcpp::GlobalAddDescriptorsName(dependency->name()));
+ // Call its AddDescriptors function.
+ printer->Print(
+ "$name$();\n",
+ "name", add_desc_name);
+ }
+
+ if (pbcpp::HasDescriptorMethods(file_))
+ {
+ // Embed the descriptor. We simply serialize the entire FileDescriptorProto
+ // and embed it as a string literal, which is parsed and built into real
+ // descriptors at initialization time.
+ pb::FileDescriptorProto file_proto;
+ file_->CopyTo(&file_proto);
+ std::string file_data;
+ file_proto.SerializeToString(&file_data);
+
+ printer->Print(
+ "::google::protobuf::DescriptorPool::InternalAddGeneratedFile(");
+
+ // Only write 40 bytes per line.
+ static const int kBytesPerLine = 40;
+ for (int i = 0; i < file_data.size(); i += kBytesPerLine)
+ {
+ printer->Print("\n \"$data$\"",
+ "data",
+ pbcpp::EscapeTrigraphs(
+ pb::CEscape(file_data.substr(i, kBytesPerLine))));
+ }
+ printer->Print(
+ ", $size$);\n",
+ "size", pb::SimpleItoa(file_data.size()));
+
+ // Call MessageFactory::InternalRegisterGeneratedFile().
+ printer->Print(
+ "::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(\n"
+ " \"$filename$\", &protobuf_RegisterTypes);\n",
+ "filename", file_->name());
+ }
+
+ // Allocate and initialize default instances. This can't be done lazily
+ // since default instances are returned by simple accessors and are used with
+ // extensions. Speaking of which, we also register extensions at this time.
+ for (int i = 0; i < file_->message_type_count(); i++)
+ {
+ message_generators_[i]->GenerateDefaultInstanceAllocator(printer);
+ }
+ for (int i = 0; i < file_->extension_count(); i++)
+ {
+ extension_generators_[i]->GenerateRegistration(printer);
+ }
+ for (int i = 0; i < file_->message_type_count(); i++)
+ {
+ message_generators_[i]->GenerateDefaultInstanceInitializer(printer);
+ }
+
+ printer->Print(
+ "::google::protobuf::internal::OnShutdown(&$shutdownfilename$);\n",
+ "shutdownfilename", pbcpp::GlobalShutdownFileName(file_->name()));
+
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "\n");
+
+ pbcpp::PrintHandlingOptionalStaticInitializers(
+ file_, printer,
+ // With static initializers.
+ "// Force AddDescriptors() to be called at static initialization time.\n"
+ "struct StaticDescriptorInitializer_$filename$ {\n"
+ " StaticDescriptorInitializer_$filename$() {\n"
+ " $adddescriptorsname$();\n"
+ " }\n"
+ "} static_descriptor_initializer_$filename$_;\n",
+ // Without.
+ "GOOGLE_PROTOBUF_DECLARE_ONCE($adddescriptorsname$_once_);\n"
+ "void $adddescriptorsname$() {\n"
+ " ::google::protobuf::GoogleOnceInit(&$adddescriptorsname$_once_,\n"
+ " &$adddescriptorsname$_impl);\n"
+ "}\n",
+ // Vars.
+ "adddescriptorsname", pbcpp::GlobalAddDescriptorsName(file_->name()),
+ "filename", pbcpp::FilenameIdentifier(file_->name()));
+}
+
+void BnetFileGenerator::GenerateNamespaceOpeners(pb::io::Printer* printer)
+{
+ if (package_parts_.size() > 0)
+ printer->Print("\n");
+
+ for (int i = 0; i < package_parts_.size(); i++)
+ {
+ printer->Print("namespace $part$ {\n",
+ "part", package_parts_[i]);
+ }
+}
+
+void BnetFileGenerator::GenerateNamespaceClosers(pb::io::Printer* printer)
+{
+ if (package_parts_.size() > 0)
+ printer->Print("\n");
+
+ for (int i = package_parts_.size() - 1; i >= 0; i--)
+ {
+ printer->Print("} // namespace $part$\n",
+ "part", package_parts_[i]);
+ }
+}
diff --git a/contrib/protoc-bnet/BnetFileGenerator.h b/contrib/protoc-bnet/BnetFileGenerator.h
new file mode 100644
index 00000000000..3beba7a8852
--- /dev/null
+++ b/contrib/protoc-bnet/BnetFileGenerator.h
@@ -0,0 +1,109 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_FILE_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_FILE_H__
+
+#include <memory>
+#include <string>
+#include <vector>
+#include <google/protobuf/stubs/common.h>
+#include "google/protobuf/compiler/cpp/cpp_field.h"
+#include "google/protobuf/compiler/cpp/cpp_options.h"
+
+class BnetServiceGenerator; // service.h
+
+namespace google
+{
+ namespace protobuf
+ {
+ class FileDescriptor; // descriptor.h
+ namespace io
+ {
+ class Printer; // printer.h
+ }
+ }
+
+ namespace protobuf
+ {
+ namespace compiler
+ {
+ namespace cpp
+ {
+
+ class EnumGenerator; // enum.h
+ class MessageGenerator; // message.h
+ class ExtensionGenerator; // extension.h
+ }
+ }
+ }
+}
+
+namespace pb = google::protobuf;
+namespace pbcpp = pb::compiler::cpp;
+
+class BnetFileGenerator
+{
+public:
+ // See generator.cc for the meaning of dllexport_decl.
+ explicit BnetFileGenerator(const pb::FileDescriptor* file,
+ const pbcpp::Options& options);
+ ~BnetFileGenerator();
+
+ void GenerateHeader(pb::io::Printer* printer);
+ void GenerateSource(pb::io::Printer* printer);
+
+private:
+ // Generate the BuildDescriptors() procedure, which builds all descriptors
+ // for types defined in the file.
+ void GenerateBuildDescriptors(pb::io::Printer* printer);
+
+ void GenerateNamespaceOpeners(pb::io::Printer* printer);
+ void GenerateNamespaceClosers(pb::io::Printer* printer);
+
+ const pb::FileDescriptor* file_;
+
+ pb::scoped_array<pb::scoped_ptr<pbcpp::MessageGenerator>> message_generators_;
+ pb::scoped_array<pb::scoped_ptr<pbcpp::EnumGenerator>> enum_generators_;
+ pb::scoped_array<pb::scoped_ptr<BnetServiceGenerator>> service_generators_;
+ pb::scoped_array<pb::scoped_ptr<pbcpp::ExtensionGenerator>> extension_generators_;
+
+ // E.g. if the package is foo.bar, package_parts_ is {"foo", "bar"}.
+ std::vector<std::string> package_parts_;
+ const pbcpp::Options options_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(BnetFileGenerator);
+};
+
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_FILE_H__
diff --git a/contrib/protoc-bnet/BnetServiceGenerator.cpp b/contrib/protoc-bnet/BnetServiceGenerator.cpp
new file mode 100644
index 00000000000..a47df61f6bf
--- /dev/null
+++ b/contrib/protoc-bnet/BnetServiceGenerator.cpp
@@ -0,0 +1,312 @@
+//
+// Created by tea on 10.03.16.
+//
+
+#include "BnetServiceGenerator.h"
+#include "method_options.pb.h"
+#include "service_options.pb.h"
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/compiler/cpp/cpp_helpers.h>
+#include "google/protobuf/compiler/cpp/cpp_options.h"
+
+BnetServiceGenerator::BnetServiceGenerator(pb::ServiceDescriptor const* descriptor, pbcpp::Options const& options) : descriptor_(descriptor)
+{
+ vars_["classname"] = descriptor_->name();
+ vars_["full_name"] = descriptor_->full_name();
+ if (options.dllexport_decl.empty())
+ vars_["dllexport"] = "";
+ else
+ vars_["dllexport"] = options.dllexport_decl + " ";
+
+ vars_["original_hash"] = " typedef std::integral_constant<uint32, 0x" + pb::ToUpper(pb::ToHex(HashServiceName(descriptor_->options().GetExtension(Battlenet::original_fully_qualified_descriptor_name)))) + "u> OriginalHash;\n";
+ vars_["name_hash"] = " typedef std::integral_constant<uint32, 0x" + pb::ToUpper(pb::ToHex(HashServiceName(descriptor_->full_name()))) + "u> NameHash;\n";
+}
+
+BnetServiceGenerator::~BnetServiceGenerator() { }
+
+void BnetServiceGenerator::GenerateDeclarations(pb::io::Printer* printer)
+{
+ GenerateInterface(printer);
+}
+
+void BnetServiceGenerator::GenerateInterface(pb::io::Printer* printer)
+{
+ printer->Print(vars_,
+ "class $dllexport$$classname$ : public ServiceBase\n"
+ "{\n"
+ " public:\n"
+ "\n"
+ " template<typename HashSelector>\n"
+ " explicit $classname$(HashSelector) : service_hash_(HashSelector::Result::value) { }\n"
+ "\n"
+ "$original_hash$"
+ "$name_hash$");
+
+ printer->Indent();
+
+ printer->Print(vars_,
+ "\n"
+ "static google::protobuf::ServiceDescriptor const* descriptor();\n"
+ "\n"
+ "// client methods --------------------------------------------------\n"
+ "\n");
+
+ GenerateClientMethodSignatures(printer);
+
+ printer->Print(
+ "// server methods --------------------------------------------------\n"
+ "\n"
+ "void CallServerMethod(uint32 token, uint32 methodId, MessageBuffer buffer) override final;\n"
+ "\n");
+
+ printer->Outdent();
+
+ printer->Print(" protected:\n ");
+
+ printer->Indent();
+
+ GenerateServerMethodSignatures(printer);
+
+ printer->Outdent();
+
+ printer->Print(vars_,
+ "\n"
+ " private:\n"
+ " uint32 service_hash_;\n"
+ "\n"
+ " GOOGLE_DISALLOW_EVIL_CONSTRUCTORS($classname$);\n"
+ "};\n");
+}
+
+void BnetServiceGenerator::GenerateClientMethodSignatures(pb::io::Printer* printer)
+{
+ for (int i = 0; i < descriptor_->method_count(); i++)
+ {
+ pb::MethodDescriptor const* method = descriptor_->method(i);
+ if (!method->options().HasExtension(Battlenet::method_id))
+ continue;
+
+ std::map<std::string, std::string> sub_vars;
+ sub_vars["name"] = method->name();
+ sub_vars["full_name"] = descriptor_->name() + "." + method->name();
+ sub_vars["method_id"] = pb::SimpleItoa(method->options().GetExtension(Battlenet::method_id));
+ sub_vars["input_type"] = pbcpp::ClassName(method->input_type(), true);
+ sub_vars["output_type"] = pbcpp::ClassName(method->output_type(), true);
+ sub_vars["input_type_name"] = method->input_type()->full_name();
+
+ if (method->output_type()->name() != "NO_RESPONSE")
+ printer->Print(sub_vars, "void $name$($input_type$ const* request, std::function<void($output_type$ const*)> responseCallback);\n");
+ else
+ printer->Print(sub_vars, "void $name$($input_type$ const* request);\n");
+ }
+}
+
+void BnetServiceGenerator::GenerateServerMethodSignatures(pb::io::Printer* printer)
+{
+ for (int i = 0; i < descriptor_->method_count(); i++)
+ {
+ pb::MethodDescriptor const* method = descriptor_->method(i);
+ if (!method->options().HasExtension(Battlenet::method_id))
+ continue;
+
+ std::map<std::string, std::string> sub_vars;
+ sub_vars["name"] = method->name();
+ sub_vars["input_type"] = pbcpp::ClassName(method->input_type(), true);
+ sub_vars["output_type"] = pbcpp::ClassName(method->output_type(), true);
+
+ if (method->output_type()->name() != "NO_RESPONSE")
+ printer->Print(sub_vars, "virtual uint32 Handle$name$($input_type$ const* request, $output_type$* response);\n");
+ else
+ printer->Print(sub_vars, "virtual uint32 Handle$name$($input_type$ const* request);\n");
+ }
+}
+
+// ===================================================================
+
+void BnetServiceGenerator::GenerateDescriptorInitializer(pb::io::Printer* printer, int index)
+{
+ std::map<std::string, std::string> vars;
+ vars["classname"] = descriptor_->name();
+ vars["index"] = pb::SimpleItoa(index);
+
+ printer->Print(vars, "$classname$_descriptor_ = file->service($index$);\n");
+}
+
+// ===================================================================
+
+void BnetServiceGenerator::GenerateImplementation(pb::io::Printer* printer)
+{
+ printer->Print(vars_,
+ "google::protobuf::ServiceDescriptor const* $classname$::descriptor() {\n"
+ " protobuf_AssignDescriptorsOnce();\n"
+ " return $classname$_descriptor_;\n"
+ "}\n"
+ "\n");
+
+ GenerateClientMethodImplementations(printer);
+ GenerateServerCallMethod(printer);
+ GenerateServerImplementations(printer);
+}
+
+void BnetServiceGenerator::GenerateClientMethodImplementations(pb::io::Printer* printer)
+{
+ for (int i = 0; i < descriptor_->method_count(); i++)
+ {
+ pb::MethodDescriptor const* method = descriptor_->method(i);
+ if (!method->options().HasExtension(Battlenet::method_id))
+ continue;
+
+ std::map<std::string, std::string> sub_vars;
+ sub_vars["classname"] = vars_["classname"];
+ sub_vars["name"] = method->name();
+ sub_vars["full_name"] = descriptor_->name() + "." + method->name();
+ sub_vars["method_id"] = pb::SimpleItoa(method->options().GetExtension(Battlenet::method_id));
+ sub_vars["input_type"] = pbcpp::ClassName(method->input_type(), true);
+ sub_vars["output_type"] = pbcpp::ClassName(method->output_type(), true);
+ sub_vars["input_type_name"] = method->input_type()->full_name();
+
+ if (method->output_type()->name() != "NO_RESPONSE")
+ {
+ printer->Print(sub_vars,
+ "void $classname$::$name$($input_type$ const* request, std::function<void($output_type$ const*)> responseCallback) { \n"
+ " TC_LOG_DEBUG(\"service.protobuf\", \"%s Server called client method $full_name$($input_type_name${ %s })\",\n"
+ " GetCallerInfo().c_str(), request->ShortDebugString().c_str());\n"
+ " SendRequest(service_hash_, $method_id$, request, [callback{ std::move(responseCallback) }](MessageBuffer buffer) {\n"
+ " $output_type$ response;\n"
+ " if (response.ParseFromArray(buffer.GetReadPointer(), buffer.GetActiveSize()))\n"
+ " callback(&response);\n"
+ " });\n"
+ "}\n"
+ "\n");
+ }
+ else
+ {
+ printer->Print(sub_vars,
+ "void $classname$::$name$($input_type$ const* request) { \n"
+ " TC_LOG_DEBUG(\"service.protobuf\", \"%s Server called client method $full_name$($input_type_name${ %s })\",\n"
+ " GetCallerInfo().c_str(), request->ShortDebugString().c_str());\n"
+ " SendRequest(service_hash_, $method_id$, request);\n"
+ "}\n"
+ "\n");
+ }
+ }
+}
+
+void BnetServiceGenerator::GenerateServerCallMethod(pb::io::Printer* printer)
+{
+ printer->Print(vars_,
+ "void $classname$::CallServerMethod(uint32 token, uint32 methodId, MessageBuffer buffer) {\n"
+ " switch(methodId) {\n");
+
+ for (int i = 0; i < descriptor_->method_count(); i++)
+ {
+ pb::MethodDescriptor const* method = descriptor_->method(i);
+ if (!method->options().HasExtension(Battlenet::method_id))
+ continue;
+
+ std::map<std::string, std::string> sub_vars;
+ sub_vars["name"] = method->name();
+ sub_vars["full_name"] = descriptor_->name() + "." + method->name();
+ sub_vars["method_id"] = pb::SimpleItoa(method->options().GetExtension(Battlenet::method_id));
+ sub_vars["input_type"] = pbcpp::ClassName(method->input_type(), true);
+ sub_vars["output_type"] = pbcpp::ClassName(method->output_type(), true);
+ sub_vars["input_type_name"] = method->input_type()->full_name();
+ sub_vars["output_type_name"] = method->output_type()->full_name();
+
+ printer->Print(sub_vars,
+ " case $method_id$: {\n"
+ " $input_type$ request;\n"
+ " if (!request.ParseFromArray(buffer.GetReadPointer(), buffer.GetActiveSize())) {\n"
+ " TC_LOG_DEBUG(\"service.protobuf\", \"%s Failed to parse request for $full_name$ server method call.\", GetCallerInfo().c_str());\n"
+ " SendResponse(service_hash_, $method_id$, token, ERROR_RPC_MALFORMED_REQUEST);\n"
+ " return;\n"
+ " }\n"
+ "\n"
+ );
+
+ if (method->output_type()->name() != "NO_RESPONSE")
+ {
+ printer->Print(sub_vars,
+ " $output_type$ response;\n"
+ " uint32 status = Handle$name$(&request, &response);\n"
+ " TC_LOG_DEBUG(\"service.protobuf\", \"%s Client called server method $full_name$($input_type_name${ %s }) returned $output_type_name${ %s } status %u.\",\n"
+ " GetCallerInfo().c_str(), request.ShortDebugString().c_str(), response.ShortDebugString().c_str(), status);\n"
+ " if (!status)\n"
+ " SendResponse(service_hash_, $method_id$, token, &response);\n"
+ " else\n"
+ " SendResponse(service_hash_, $method_id$, token, status);\n");
+ }
+ else
+ {
+ printer->Print(sub_vars,
+ " uint32 status = Handle$name$(&request);\n"
+ " TC_LOG_DEBUG(\"service.protobuf\", \"%s Client called server method $full_name$($input_type_name${ %s }) status %u.\",\n"
+ " GetCallerInfo().c_str(), request.ShortDebugString().c_str(), status);\n"
+ " if (status)\n"
+ " SendResponse(service_hash_, $method_id$, token, status);\n");
+ }
+
+ printer->Print(sub_vars,
+ " break;\n"
+ " }\n");
+ }
+
+ printer->Print(vars_,
+ " default:\n"
+ " TC_LOG_ERROR(\"service.protobuf\", \"Bad method id %u.\", methodId);\n"
+ " SendResponse(service_hash_, methodId, token, ERROR_RPC_INVALID_METHOD);\n"
+ " break;\n"
+ " }\n"
+ "}\n"
+ "\n");
+}
+
+void BnetServiceGenerator::GenerateServerImplementations(pb::io::Printer* printer)
+{
+ for (int i = 0; i < descriptor_->method_count(); i++)
+ {
+ pb::MethodDescriptor const* method = descriptor_->method(i);
+ if (!method->options().HasExtension(Battlenet::method_id))
+ continue;
+
+ std::map<std::string, std::string> sub_vars;
+ sub_vars["classname"] = vars_["classname"];
+ sub_vars["name"] = method->name();
+ sub_vars["full_name"] = descriptor_->name() + "." + method->name();
+ sub_vars["input_type"] = pbcpp::ClassName(method->input_type(), true);
+ sub_vars["output_type"] = pbcpp::ClassName(method->output_type(), true);
+
+ if (method->output_type()->name() != "NO_RESPONSE")
+ {
+ printer->Print(sub_vars, "uint32 $classname$::Handle$name$($input_type$ const* request, $output_type$* response) {\n"
+ " TC_LOG_ERROR(\"service.protobuf\", \"%s Client tried to call not implemented method $full_name$({ %s })\",\n"
+ " GetCallerInfo().c_str(), request->ShortDebugString().c_str());\n"
+ " return ERROR_RPC_NOT_IMPLEMENTED;\n"
+ "}\n"
+ "\n");
+ }
+ else
+ {
+ printer->Print(sub_vars, "uint32 $classname$::Handle$name$($input_type$ const* request) {\n"
+ " TC_LOG_ERROR(\"service.protobuf\", \"%s Client tried to call not implemented method $full_name$({ %s })\",\n"
+ " GetCallerInfo().c_str(), request->ShortDebugString().c_str());\n"
+ " return ERROR_RPC_NOT_IMPLEMENTED;\n"
+ "}\n"
+ "\n");
+ }
+ }
+}
+
+std::uint32_t BnetServiceGenerator::HashServiceName(std::string const& name)
+{
+ std::uint32_t hash = 0x811C9DC5;
+ for (std::size_t i = 0; i < name.length(); ++i)
+ {
+ hash ^= name[i];
+ hash *= 0x1000193;
+ }
+
+ return hash;
+}
diff --git a/contrib/protoc-bnet/BnetServiceGenerator.h b/contrib/protoc-bnet/BnetServiceGenerator.h
new file mode 100644
index 00000000000..2debe8d5436
--- /dev/null
+++ b/contrib/protoc-bnet/BnetServiceGenerator.h
@@ -0,0 +1,86 @@
+//
+// Created by tea on 10.03.16.
+//
+
+#ifndef PROTOC_BNET_BNETSERVICEGENERATOR_H
+#define PROTOC_BNET_BNETSERVICEGENERATOR_H
+
+#include <google/protobuf/stubs/common.h>
+#include <cstdint>
+#include <string>
+#include <map>
+
+namespace google
+{
+ namespace protobuf
+ {
+ class ServiceDescriptor;
+
+ namespace io
+ {
+ class Printer;
+ }
+
+ namespace compiler
+ {
+ namespace cpp
+ {
+ struct Options;
+ }
+ }
+ }
+}
+
+namespace pb = google::protobuf;
+namespace pbcpp = pb::compiler::cpp;
+
+class BnetServiceGenerator
+{
+public:
+ // See generator.cc for the meaning of dllexport_decl.
+ BnetServiceGenerator(const pb::ServiceDescriptor* descriptor,
+ const pbcpp::Options& options);
+ ~BnetServiceGenerator();
+
+ // Header stuff.
+
+ // Generate the class definitions for the service's interface and the
+ // stub implementation.
+ void GenerateDeclarations(pb::io::Printer* printer);
+
+ // Source file stuff.
+
+ // Generate code that initializes the global variable storing the service's
+ // descriptor.
+ void GenerateDescriptorInitializer(pb::io::Printer* printer, int index);
+
+ // Generate implementations of everything declared by GenerateDeclarations().
+ void GenerateImplementation(pb::io::Printer* printer);
+
+private:
+ // Header stuff.
+
+ // Generate the service abstract interface.
+ void GenerateInterface(pb::io::Printer* printer);
+
+ // Prints signatures for all methods in the
+ void GenerateClientMethodSignatures(pb::io::Printer* printer);
+ void GenerateServerMethodSignatures(pb::io::Printer* printer);
+
+ // Source file stuff.
+
+ void GenerateClientMethodImplementations(pb::io::Printer* printer);
+
+ // Generate the CallMethod() method of the service.
+ void GenerateServerCallMethod(pb::io::Printer* printer);
+ void GenerateServerImplementations(pb::io::Printer* printer);
+
+ std::uint32_t HashServiceName(std::string const& name);
+
+ const pb::ServiceDescriptor* descriptor_;
+ std::map<std::string, std::string> vars_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(BnetServiceGenerator);
+};
+
+#endif //PROTOC_BNET_BNETSERVICEGENERATOR_H
diff --git a/contrib/protoc-bnet/CMakeLists.txt b/contrib/protoc-bnet/CMakeLists.txt
new file mode 100644
index 00000000000..77cecaecdb0
--- /dev/null
+++ b/contrib/protoc-bnet/CMakeLists.txt
@@ -0,0 +1,32 @@
+cmake_minimum_required(VERSION 3.0)
+project(protoc_bnet)
+
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+
+find_package(Protobuf REQUIRED)
+
+file(GLOB_RECURSE SOURCE_PROTOBUF_CPP google/protobuf/*.cc)
+
+set(SOURCE_FILES
+ main.cpp
+ BnetCodeGenerator.cpp
+ BnetFileGenerator.cpp
+ BnetServiceGenerator.cpp
+ method_options.pb.cc
+ service_options.pb.cc
+ ${SOURCE_PROTOBUF_CPP})
+
+include_directories(${CMAKE_SOURCE_DIR} ${PROTOBUF_INCLUDE_DIRS})
+
+add_executable(protoc-gen-bnet ${SOURCE_FILES})
+
+target_link_libraries(protoc-gen-bnet ${PROTOBUF_PROTOC_LIBRARIES} ${PROTOBUF_LIBRARIES})
+
+set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR})
+
+add_custom_target(install_plugin
+ make install
+ DEPENDS protoc-gen-bnet
+ COMMENT "Installing protoc_bnet")
+
+install(TARGETS protoc-gen-bnet DESTINATION bin)
diff --git a/contrib/protoc-bnet/config.h b/contrib/protoc-bnet/config.h
new file mode 100644
index 00000000000..87b24386b1c
--- /dev/null
+++ b/contrib/protoc-bnet/config.h
@@ -0,0 +1,31 @@
+/* protobuf config.h for MSVC. On other platforms, this is generated
+* automatically by autoheader / autoconf / configure. */
+
+#define _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS
+
+/* the location of <hash_map> */
+#define HASH_MAP_H <hash_map>
+
+/* the namespace of hash_map/hash_set */
+// Apparently Microsoft decided to move hash_map *back* to the std namespace
+// in MSVC 2010:
+// http://blogs.msdn.com/vcblog/archive/2009/05/25/stl-breaking-changes-in-visual-studio-2010-beta-1.aspx
+// TODO(kenton): Use unordered_map instead, which is available in MSVC 2010.
+#if _MSC_VER < 1310 || _MSC_VER >= 1600
+#define HASH_NAMESPACE std
+#else
+#define HASH_NAMESPACE stdext
+#endif
+
+/* the location of <hash_set> */
+#define HASH_SET_H <hash_set>
+
+/* define if the compiler has hash_map */
+#define HAVE_HASH_MAP 1
+
+/* define if the compiler has hash_set */
+#define HAVE_HASH_SET 1
+
+/* define if you want to use zlib. See readme.txt for additional
+* requirements. */
+// #define HAVE_ZLIB 1
diff --git a/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_enum.cc b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_enum.cc
new file mode 100644
index 00000000000..7200459985e
--- /dev/null
+++ b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_enum.cc
@@ -0,0 +1,288 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <set>
+#include <map>
+
+#include "google/protobuf/compiler/cpp/cpp_enum.h"
+#include "google/protobuf/compiler/cpp/cpp_helpers.h"
+#include <google/protobuf/io/printer.h>
+#include "google/protobuf/stubs/strutil.h"
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+namespace {
+// The GOOGLE_ARRAYSIZE constant is the max enum value plus 1. If the max enum value
+// is kint32max, GOOGLE_ARRAYSIZE will overflow. In such cases we should omit the
+// generation of the GOOGLE_ARRAYSIZE constant.
+bool ShouldGenerateArraySize(const EnumDescriptor* descriptor) {
+ int32 max_value = descriptor->value(0)->number();
+ for (int i = 0; i < descriptor->value_count(); i++) {
+ if (descriptor->value(i)->number() > max_value) {
+ max_value = descriptor->value(i)->number();
+ }
+ }
+ return max_value != kint32max;
+}
+} // namespace
+
+EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor,
+ const Options& options)
+ : descriptor_(descriptor),
+ classname_(ClassName(descriptor, false)),
+ options_(options),
+ generate_array_size_(ShouldGenerateArraySize(descriptor)) {
+}
+
+EnumGenerator::~EnumGenerator() {}
+
+void EnumGenerator::GenerateDefinition(io::Printer* printer) {
+ map<string, string> vars;
+ vars["classname"] = classname_;
+ vars["short_name"] = descriptor_->name();
+
+ printer->Print(vars, "enum $classname$ {\n");
+ printer->Indent();
+
+ const EnumValueDescriptor* min_value = descriptor_->value(0);
+ const EnumValueDescriptor* max_value = descriptor_->value(0);
+
+ for (int i = 0; i < descriptor_->value_count(); i++) {
+ vars["name"] = descriptor_->value(i)->name();
+ // In C++, an value of -2147483648 gets interpreted as the negative of
+ // 2147483648, and since 2147483648 can't fit in an integer, this produces a
+ // compiler warning. This works around that issue.
+ vars["number"] = Int32ToString(descriptor_->value(i)->number());
+ vars["prefix"] = (descriptor_->containing_type() == NULL) ?
+ "" : classname_ + "_";
+
+ if (i > 0) printer->Print(",\n");
+ printer->Print(vars, "$prefix$$name$ = $number$");
+
+ if (descriptor_->value(i)->number() < min_value->number()) {
+ min_value = descriptor_->value(i);
+ }
+ if (descriptor_->value(i)->number() > max_value->number()) {
+ max_value = descriptor_->value(i);
+ }
+ }
+
+ printer->Outdent();
+ printer->Print("\n};\n");
+
+ vars["min_name"] = min_value->name();
+ vars["max_name"] = max_value->name();
+
+ if (options_.dllexport_decl.empty()) {
+ vars["dllexport"] = "";
+ } else {
+ vars["dllexport"] = options_.dllexport_decl + " ";
+ }
+
+ printer->Print(vars,
+ "$dllexport$bool $classname$_IsValid(int value);\n"
+ "const $classname$ $prefix$$short_name$_MIN = $prefix$$min_name$;\n"
+ "const $classname$ $prefix$$short_name$_MAX = $prefix$$max_name$;\n");
+
+ if (generate_array_size_) {
+ printer->Print(vars,
+ "const int $prefix$$short_name$_ARRAYSIZE = "
+ "$prefix$$short_name$_MAX + 1;\n\n");
+ }
+
+ if (HasDescriptorMethods(descriptor_->file())) {
+ printer->Print(vars,
+ "$dllexport$const ::google::protobuf::EnumDescriptor* $classname$_descriptor();\n");
+ // The _Name and _Parse methods
+ printer->Print(vars,
+ "inline const ::std::string& $classname$_Name($classname$ value) {\n"
+ " return ::google::protobuf::internal::NameOfEnum(\n"
+ " $classname$_descriptor(), value);\n"
+ "}\n");
+ printer->Print(vars,
+ "inline bool $classname$_Parse(\n"
+ " const ::std::string& name, $classname$* value) {\n"
+ " return ::google::protobuf::internal::ParseNamedEnum<$classname$>(\n"
+ " $classname$_descriptor(), name, value);\n"
+ "}\n");
+ }
+}
+
+void EnumGenerator::
+GenerateGetEnumDescriptorSpecializations(io::Printer* printer) {
+ if (HasDescriptorMethods(descriptor_->file())) {
+ printer->Print(
+ "template <> struct is_proto_enum< $classname$> : ::google::protobuf::internal::true_type {};\n"
+ "template <>\n"
+ "inline const EnumDescriptor* GetEnumDescriptor< $classname$>() {\n"
+ " return $classname$_descriptor();\n"
+ "}\n",
+ "classname", ClassName(descriptor_, true));
+ }
+}
+
+void EnumGenerator::GenerateSymbolImports(io::Printer* printer) {
+ map<string, string> vars;
+ vars["nested_name"] = descriptor_->name();
+ vars["classname"] = classname_;
+ printer->Print(vars, "typedef $classname$ $nested_name$;\n");
+
+ for (int j = 0; j < descriptor_->value_count(); j++) {
+ vars["tag"] = descriptor_->value(j)->name();
+ printer->Print(vars,
+ "static const $nested_name$ $tag$ = $classname$_$tag$;\n");
+ }
+
+ printer->Print(vars,
+ "static inline bool $nested_name$_IsValid(int value) {\n"
+ " return $classname$_IsValid(value);\n"
+ "}\n"
+ "static const $nested_name$ $nested_name$_MIN =\n"
+ " $classname$_$nested_name$_MIN;\n"
+ "static const $nested_name$ $nested_name$_MAX =\n"
+ " $classname$_$nested_name$_MAX;\n");
+ if (generate_array_size_) {
+ printer->Print(vars,
+ "static const int $nested_name$_ARRAYSIZE =\n"
+ " $classname$_$nested_name$_ARRAYSIZE;\n");
+ }
+
+ if (HasDescriptorMethods(descriptor_->file())) {
+ printer->Print(vars,
+ "static inline const ::google::protobuf::EnumDescriptor*\n"
+ "$nested_name$_descriptor() {\n"
+ " return $classname$_descriptor();\n"
+ "}\n");
+ printer->Print(vars,
+ "static inline const ::std::string& $nested_name$_Name($nested_name$ value) {\n"
+ " return $classname$_Name(value);\n"
+ "}\n");
+ printer->Print(vars,
+ "static inline bool $nested_name$_Parse(const ::std::string& name,\n"
+ " $nested_name$* value) {\n"
+ " return $classname$_Parse(name, value);\n"
+ "}\n");
+ }
+}
+
+void EnumGenerator::GenerateDescriptorInitializer(
+ io::Printer* printer, int index) {
+ map<string, string> vars;
+ vars["classname"] = classname_;
+ vars["index"] = SimpleItoa(index);
+
+ if (descriptor_->containing_type() == NULL) {
+ printer->Print(vars,
+ "$classname$_descriptor_ = file->enum_type($index$);\n");
+ } else {
+ vars["parent"] = ClassName(descriptor_->containing_type(), false);
+ printer->Print(vars,
+ "$classname$_descriptor_ = $parent$_descriptor_->enum_type($index$);\n");
+ }
+}
+
+void EnumGenerator::GenerateMethods(io::Printer* printer) {
+ map<string, string> vars;
+ vars["classname"] = classname_;
+
+ if (HasDescriptorMethods(descriptor_->file())) {
+ printer->Print(vars,
+ "const ::google::protobuf::EnumDescriptor* $classname$_descriptor() {\n"
+ " protobuf_AssignDescriptorsOnce();\n"
+ " return $classname$_descriptor_;\n"
+ "}\n");
+ }
+
+ printer->Print(vars,
+ "bool $classname$_IsValid(int value) {\n"
+ " switch(value) {\n");
+
+ // Multiple values may have the same number. Make sure we only cover
+ // each number once by first constructing a set containing all valid
+ // numbers, then printing a case statement for each element.
+
+ set<int> numbers;
+ for (int j = 0; j < descriptor_->value_count(); j++) {
+ const EnumValueDescriptor* value = descriptor_->value(j);
+ numbers.insert(value->number());
+ }
+
+ for (set<int>::iterator iter = numbers.begin();
+ iter != numbers.end(); ++iter) {
+ printer->Print(
+ " case $number$:\n",
+ "number", Int32ToString(*iter));
+ }
+
+ printer->Print(vars,
+ " return true;\n"
+ " default:\n"
+ " return false;\n"
+ " }\n"
+ "}\n"
+ "\n");
+
+ if (descriptor_->containing_type() != NULL) {
+ // We need to "define" the static constants which were declared in the
+ // header, to give the linker a place to put them. Or at least the C++
+ // standard says we have to. MSVC actually insists tha we do _not_ define
+ // them again in the .cc file.
+ printer->Print("#ifndef _MSC_VER\n");
+
+ vars["parent"] = ClassName(descriptor_->containing_type(), false);
+ vars["nested_name"] = descriptor_->name();
+ for (int i = 0; i < descriptor_->value_count(); i++) {
+ vars["value"] = descriptor_->value(i)->name();
+ printer->Print(vars,
+ "const $classname$ $parent$::$value$;\n");
+ }
+ printer->Print(vars,
+ "const $classname$ $parent$::$nested_name$_MIN;\n"
+ "const $classname$ $parent$::$nested_name$_MAX;\n");
+ if (generate_array_size_) {
+ printer->Print(vars,
+ "const int $parent$::$nested_name$_ARRAYSIZE;\n");
+ }
+
+ printer->Print("#endif // _MSC_VER\n");
+ }
+}
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_enum.h b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_enum.h
new file mode 100644
index 00000000000..4e4670eac82
--- /dev/null
+++ b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_enum.h
@@ -0,0 +1,103 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__
+
+#include <string>
+#include "google/protobuf/compiler/cpp/cpp_options.h"
+#include <google/protobuf/descriptor.h>
+
+
+namespace google {
+namespace protobuf {
+ namespace io {
+ class Printer; // printer.h
+ }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class EnumGenerator {
+ public:
+ // See generator.cc for the meaning of dllexport_decl.
+ explicit EnumGenerator(const EnumDescriptor* descriptor,
+ const Options& options);
+ ~EnumGenerator();
+
+ // Header stuff.
+
+ // Generate header code defining the enum. This code should be placed
+ // within the enum's package namespace, but NOT within any class, even for
+ // nested enums.
+ void GenerateDefinition(io::Printer* printer);
+
+ // Generate specialization of GetEnumDescriptor<MyEnum>().
+ // Precondition: in ::google::protobuf namespace.
+ void GenerateGetEnumDescriptorSpecializations(io::Printer* printer);
+
+ // For enums nested within a message, generate code to import all the enum's
+ // symbols (e.g. the enum type name, all its values, etc.) into the class's
+ // namespace. This should be placed inside the class definition in the
+ // header.
+ void GenerateSymbolImports(io::Printer* printer);
+
+ // Source file stuff.
+
+ // Generate code that initializes the global variable storing the enum's
+ // descriptor.
+ void GenerateDescriptorInitializer(io::Printer* printer, int index);
+
+ // Generate non-inline methods related to the enum, such as IsValidValue().
+ // Goes in the .cc file.
+ void GenerateMethods(io::Printer* printer);
+
+ private:
+ const EnumDescriptor* descriptor_;
+ string classname_;
+ Options options_;
+ // whether to generate the *_ARRAYSIZE constant.
+ bool generate_array_size_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator);
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__
diff --git a/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_enum_field.cc b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_enum_field.cc
new file mode 100644
index 00000000000..72f363bb378
--- /dev/null
+++ b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_enum_field.cc
@@ -0,0 +1,431 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include "google/protobuf/compiler/cpp/cpp_enum_field.h"
+#include "google/protobuf/compiler/cpp/cpp_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 cpp {
+
+namespace {
+
+void SetEnumVariables(const FieldDescriptor* descriptor,
+ map<string, string>* variables,
+ const Options& options) {
+ SetCommonFieldVariables(descriptor, variables, options);
+ const EnumValueDescriptor* default_value = descriptor->default_value_enum();
+ (*variables)["type"] = ClassName(descriptor->enum_type(), true);
+ (*variables)["default"] = Int32ToString(default_value->number());
+ (*variables)["full_name"] = descriptor->full_name();
+}
+
+} // namespace
+
+// ===================================================================
+
+EnumFieldGenerator::
+EnumFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : descriptor_(descriptor) {
+ SetEnumVariables(descriptor, &variables_, options);
+}
+
+EnumFieldGenerator::~EnumFieldGenerator() {}
+
+void EnumFieldGenerator::
+GeneratePrivateMembers(io::Printer* printer) const {
+ printer->Print(variables_, "int $name$_;\n");
+}
+
+void EnumFieldGenerator::
+GenerateAccessorDeclarations(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline $type$ $name$() const$deprecation$;\n"
+ "inline void set_$name$($type$ value)$deprecation$;\n");
+}
+
+void EnumFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline $type$ $classname$::$name$() const {\n"
+ " // @@protoc_insertion_point(field_get:$full_name$)\n"
+ " return static_cast< $type$ >($name$_);\n"
+ "}\n"
+ "inline void $classname$::set_$name$($type$ value) {\n"
+ " assert($type$_IsValid(value));\n"
+ " set_has_$name$();\n"
+ " $name$_ = value;\n"
+ " // @@protoc_insertion_point(field_set:$full_name$)\n"
+ "}\n");
+}
+
+void EnumFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_ = $default$;\n");
+}
+
+void EnumFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+ printer->Print(variables_, "set_$name$(from.$name$());\n");
+}
+
+void EnumFieldGenerator::
+GenerateSwappingCode(io::Printer* printer) const {
+ printer->Print(variables_, "std::swap($name$_, other->$name$_);\n");
+}
+
+void EnumFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_ = $default$;\n");
+}
+
+void EnumFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+ printer->Print(variables_,
+ "int value;\n"
+ "DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n"
+ " int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(\n"
+ " input, &value)));\n"
+ "if ($type$_IsValid(value)) {\n"
+ " set_$name$(static_cast< $type$ >(value));\n");
+ if (UseUnknownFieldSet(descriptor_->file())) {
+ printer->Print(variables_,
+ "} else {\n"
+ " mutable_unknown_fields()->AddVarint($number$, value);\n");
+ } else {
+ printer->Print(
+ "} else {\n"
+ " unknown_fields_stream.WriteVarint32(tag);\n"
+ " unknown_fields_stream.WriteVarint32(value);\n");
+ }
+ printer->Print(variables_,
+ "}\n");
+}
+
+void EnumFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+ printer->Print(variables_,
+ "::google::protobuf::internal::WireFormatLite::WriteEnum(\n"
+ " $number$, this->$name$(), output);\n");
+}
+
+void EnumFieldGenerator::
+GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
+ printer->Print(variables_,
+ "target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(\n"
+ " $number$, this->$name$(), target);\n");
+}
+
+void EnumFieldGenerator::
+GenerateByteSize(io::Printer* printer) const {
+ printer->Print(variables_,
+ "total_size += $tag_size$ +\n"
+ " ::google::protobuf::internal::WireFormatLite::EnumSize(this->$name$());\n");
+}
+
+// ===================================================================
+
+EnumOneofFieldGenerator::
+EnumOneofFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : EnumFieldGenerator(descriptor, options) {
+ SetCommonOneofFieldVariables(descriptor, &variables_);
+}
+
+EnumOneofFieldGenerator::~EnumOneofFieldGenerator() {}
+
+void EnumOneofFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline $type$ $classname$::$name$() const {\n"
+ " if (has_$name$()) {\n"
+ " return static_cast< $type$ >($oneof_prefix$$name$_);\n"
+ " }\n"
+ " return static_cast< $type$ >($default$);\n"
+ "}\n"
+ "inline void $classname$::set_$name$($type$ value) {\n"
+ " assert($type$_IsValid(value));\n"
+ " if (!has_$name$()) {\n"
+ " clear_$oneof_name$();\n"
+ " set_has_$name$();\n"
+ " }\n"
+ " $oneof_prefix$$name$_ = value;\n"
+ "}\n");
+}
+
+void EnumOneofFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+ printer->Print(variables_, "$oneof_prefix$$name$_ = $default$;\n");
+}
+
+void EnumOneofFieldGenerator::
+GenerateSwappingCode(io::Printer* printer) const {
+ // Don't print any swapping code. Swapping the union will swap this field.
+}
+
+void EnumOneofFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ " $classname$_default_oneof_instance_->$name$_ = $default$;\n");
+}
+
+// ===================================================================
+
+RepeatedEnumFieldGenerator::
+RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : descriptor_(descriptor) {
+ SetEnumVariables(descriptor, &variables_, options);
+}
+
+RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {}
+
+void RepeatedEnumFieldGenerator::
+GeneratePrivateMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "::google::protobuf::RepeatedField<int> $name$_;\n");
+ if (descriptor_->options().packed()
+ && HasGeneratedMethods(descriptor_->file())) {
+ printer->Print(variables_,
+ "mutable int _$name$_cached_byte_size_;\n");
+ }
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateAccessorDeclarations(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline $type$ $name$(int index) const$deprecation$;\n"
+ "inline void set_$name$(int index, $type$ value)$deprecation$;\n"
+ "inline void add_$name$($type$ value)$deprecation$;\n");
+ printer->Print(variables_,
+ "inline const ::google::protobuf::RepeatedField<int>& $name$() const$deprecation$;\n"
+ "inline ::google::protobuf::RepeatedField<int>* mutable_$name$()$deprecation$;\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline $type$ $classname$::$name$(int index) const {\n"
+ " // @@protoc_insertion_point(field_get:$full_name$)\n"
+ " return static_cast< $type$ >($name$_.Get(index));\n"
+ "}\n"
+ "inline void $classname$::set_$name$(int index, $type$ value) {\n"
+ " assert($type$_IsValid(value));\n"
+ " $name$_.Set(index, value);\n"
+ " // @@protoc_insertion_point(field_set:$full_name$)\n"
+ "}\n"
+ "inline void $classname$::add_$name$($type$ value) {\n"
+ " assert($type$_IsValid(value));\n"
+ " $name$_.Add(value);\n"
+ " // @@protoc_insertion_point(field_add:$full_name$)\n"
+ "}\n");
+ printer->Print(variables_,
+ "inline const ::google::protobuf::RepeatedField<int>&\n"
+ "$classname$::$name$() const {\n"
+ " // @@protoc_insertion_point(field_list:$full_name$)\n"
+ " return $name$_;\n"
+ "}\n"
+ "inline ::google::protobuf::RepeatedField<int>*\n"
+ "$classname$::mutable_$name$() {\n"
+ " // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
+ " return &$name$_;\n"
+ "}\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_.Clear();\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateSwappingCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_.Swap(&other->$name$_);\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+ // Not needed for repeated fields.
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+ // Don't use ReadRepeatedPrimitive here so that the enum can be validated.
+ printer->Print(variables_,
+ "int value;\n"
+ "DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n"
+ " int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(\n"
+ " input, &value)));\n"
+ "if ($type$_IsValid(value)) {\n"
+ " add_$name$(static_cast< $type$ >(value));\n");
+ if (UseUnknownFieldSet(descriptor_->file())) {
+ printer->Print(variables_,
+ "} else {\n"
+ " mutable_unknown_fields()->AddVarint($number$, value);\n");
+ } else {
+ printer->Print(
+ "} else {\n"
+ " unknown_fields_stream.WriteVarint32(tag);\n"
+ " unknown_fields_stream.WriteVarint32(value);\n");
+ }
+ printer->Print("}\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const {
+ if (!descriptor_->options().packed()) {
+ // We use a non-inlined implementation in this case, since this path will
+ // rarely be executed.
+ printer->Print(variables_,
+ "DO_((::google::protobuf::internal::WireFormatLite::ReadPackedEnumNoInline(\n"
+ " input,\n"
+ " &$type$_IsValid,\n"
+ " this->mutable_$name$())));\n");
+ } else {
+ printer->Print(variables_,
+ "::google::protobuf::uint32 length;\n"
+ "DO_(input->ReadVarint32(&length));\n"
+ "::google::protobuf::io::CodedInputStream::Limit limit = "
+ "input->PushLimit(length);\n"
+ "while (input->BytesUntilLimit() > 0) {\n"
+ " int value;\n"
+ " DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n"
+ " int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(\n"
+ " input, &value)));\n"
+ " if ($type$_IsValid(value)) {\n"
+ " add_$name$(static_cast< $type$ >(value));\n"
+ " }\n"
+ "}\n"
+ "input->PopLimit(limit);\n");
+ }
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+ if (descriptor_->options().packed()) {
+ // Write the tag and the size.
+ printer->Print(variables_,
+ "if (this->$name$_size() > 0) {\n"
+ " ::google::protobuf::internal::WireFormatLite::WriteTag(\n"
+ " $number$,\n"
+ " ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,\n"
+ " output);\n"
+ " output->WriteVarint32(_$name$_cached_byte_size_);\n"
+ "}\n");
+ }
+ printer->Print(variables_,
+ "for (int i = 0; i < this->$name$_size(); i++) {\n");
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ " ::google::protobuf::internal::WireFormatLite::WriteEnumNoTag(\n"
+ " this->$name$(i), output);\n");
+ } else {
+ printer->Print(variables_,
+ " ::google::protobuf::internal::WireFormatLite::WriteEnum(\n"
+ " $number$, this->$name$(i), output);\n");
+ }
+ printer->Print("}\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
+ if (descriptor_->options().packed()) {
+ // Write the tag and the size.
+ printer->Print(variables_,
+ "if (this->$name$_size() > 0) {\n"
+ " target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(\n"
+ " $number$,\n"
+ " ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,\n"
+ " target);\n"
+ " target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray("
+ " _$name$_cached_byte_size_, target);\n"
+ "}\n");
+ }
+ printer->Print(variables_,
+ "for (int i = 0; i < this->$name$_size(); i++) {\n");
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ " target = ::google::protobuf::internal::WireFormatLite::WriteEnumNoTagToArray(\n"
+ " this->$name$(i), target);\n");
+ } else {
+ printer->Print(variables_,
+ " target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(\n"
+ " $number$, this->$name$(i), target);\n");
+ }
+ printer->Print("}\n");
+}
+
+void RepeatedEnumFieldGenerator::
+GenerateByteSize(io::Printer* printer) const {
+ printer->Print(variables_,
+ "{\n"
+ " int data_size = 0;\n");
+ printer->Indent();
+ printer->Print(variables_,
+ "for (int i = 0; i < this->$name$_size(); i++) {\n"
+ " data_size += ::google::protobuf::internal::WireFormatLite::EnumSize(\n"
+ " this->$name$(i));\n"
+ "}\n");
+
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ "if (data_size > 0) {\n"
+ " total_size += $tag_size$ +\n"
+ " ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);\n"
+ "}\n"
+ "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
+ "_$name$_cached_byte_size_ = data_size;\n"
+ "GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
+ "total_size += data_size;\n");
+ } else {
+ printer->Print(variables_,
+ "total_size += $tag_size$ * this->$name$_size() + data_size;\n");
+ }
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_enum_field.h b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_enum_field.h
new file mode 100644
index 00000000000..b54cf291372
--- /dev/null
+++ b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_enum_field.h
@@ -0,0 +1,122 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_FIELD_H__
+
+#include <map>
+#include <string>
+#include "google/protobuf/compiler/cpp/cpp_field.h"
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class EnumFieldGenerator : public FieldGenerator {
+ public:
+ explicit EnumFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ ~EnumFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ void GeneratePrivateMembers(io::Printer* printer) const;
+ void GenerateAccessorDeclarations(io::Printer* printer) const;
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+ void GenerateClearingCode(io::Printer* printer) const;
+ void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateSwappingCode(io::Printer* printer) const;
+ void GenerateConstructorCode(io::Printer* printer) const;
+ void GenerateMergeFromCodedStream(io::Printer* printer) const;
+ void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
+ void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
+ void GenerateByteSize(io::Printer* printer) const;
+
+ protected:
+ const FieldDescriptor* descriptor_;
+ map<string, string> variables_;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator);
+};
+
+class EnumOneofFieldGenerator : public EnumFieldGenerator {
+ public:
+ explicit EnumOneofFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ ~EnumOneofFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+ void GenerateClearingCode(io::Printer* printer) const;
+ void GenerateSwappingCode(io::Printer* printer) const;
+ void GenerateConstructorCode(io::Printer* printer) const;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumOneofFieldGenerator);
+};
+
+class RepeatedEnumFieldGenerator : public FieldGenerator {
+ public:
+ explicit RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ ~RepeatedEnumFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ void GeneratePrivateMembers(io::Printer* printer) const;
+ void GenerateAccessorDeclarations(io::Printer* printer) const;
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+ void GenerateClearingCode(io::Printer* printer) const;
+ void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateSwappingCode(io::Printer* printer) const;
+ void GenerateConstructorCode(io::Printer* printer) const;
+ void GenerateMergeFromCodedStream(io::Printer* printer) const;
+ void GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const;
+ void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
+ void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
+ void GenerateByteSize(io::Printer* printer) const;
+
+ private:
+ const FieldDescriptor* descriptor_;
+ map<string, string> variables_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedEnumFieldGenerator);
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_FIELD_H__
diff --git a/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_extension.cc b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_extension.cc
new file mode 100644
index 00000000000..0263bf61ad9
--- /dev/null
+++ b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_extension.cc
@@ -0,0 +1,210 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include "google/protobuf/compiler/cpp/cpp_extension.h"
+#include <map>
+#include "google/protobuf/compiler/cpp/cpp_helpers.h"
+#include "google/protobuf/stubs/strutil.h"
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/descriptor.pb.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+namespace {
+
+// Returns the fully-qualified class name of the message that this field
+// extends. This function is used in the Google-internal code to handle some
+// legacy cases.
+string ExtendeeClassName(const FieldDescriptor* descriptor) {
+ const Descriptor* extendee = descriptor->containing_type();
+ return ClassName(extendee, true);
+}
+
+} // anonymous namespace
+
+ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : descriptor_(descriptor),
+ options_(options) {
+ // Construct type_traits_.
+ if (descriptor_->is_repeated()) {
+ type_traits_ = "Repeated";
+ }
+
+ switch (descriptor_->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_ENUM:
+ type_traits_.append("EnumTypeTraits< ");
+ type_traits_.append(ClassName(descriptor_->enum_type(), true));
+ type_traits_.append(", ");
+ type_traits_.append(ClassName(descriptor_->enum_type(), true));
+ type_traits_.append("_IsValid>");
+ break;
+ case FieldDescriptor::CPPTYPE_STRING:
+ type_traits_.append("StringTypeTraits");
+ break;
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ type_traits_.append("MessageTypeTraits< ");
+ type_traits_.append(ClassName(descriptor_->message_type(), true));
+ type_traits_.append(" >");
+ break;
+ default:
+ type_traits_.append("PrimitiveTypeTraits< ");
+ type_traits_.append(PrimitiveTypeName(descriptor_->cpp_type()));
+ type_traits_.append(" >");
+ break;
+ }
+}
+
+ExtensionGenerator::~ExtensionGenerator() {}
+
+void ExtensionGenerator::GenerateDeclaration(io::Printer* printer) {
+ map<string, string> vars;
+ vars["extendee" ] = ExtendeeClassName(descriptor_);
+ vars["number" ] = SimpleItoa(descriptor_->number());
+ vars["type_traits" ] = type_traits_;
+ vars["name" ] = descriptor_->name();
+ vars["field_type" ] = SimpleItoa(static_cast<int>(descriptor_->type()));
+ vars["packed" ] = descriptor_->options().packed() ? "true" : "false";
+ vars["constant_name"] = FieldConstantName(descriptor_);
+
+ // If this is a class member, it needs to be declared "static". Otherwise,
+ // it needs to be "extern". In the latter case, it also needs the DLL
+ // export/import specifier.
+ if (descriptor_->extension_scope() == NULL) {
+ vars["qualifier"] = "extern";
+ if (!options_.dllexport_decl.empty()) {
+ vars["qualifier"] = options_.dllexport_decl + " " + vars["qualifier"];
+ }
+ } else {
+ vars["qualifier"] = "static";
+ }
+
+ printer->Print(vars,
+ "static const int $constant_name$ = $number$;\n"
+ "$qualifier$ ::google::protobuf::internal::ExtensionIdentifier< $extendee$,\n"
+ " ::google::protobuf::internal::$type_traits$, $field_type$, $packed$ >\n"
+ " $name$;\n"
+ );
+
+}
+
+void ExtensionGenerator::GenerateDefinition(io::Printer* printer) {
+ // If this is a class member, it needs to be declared in its class scope.
+ string scope = (descriptor_->extension_scope() == NULL) ? "" :
+ ClassName(descriptor_->extension_scope(), false) + "::";
+ string name = scope + descriptor_->name();
+
+ map<string, string> vars;
+ vars["extendee" ] = ExtendeeClassName(descriptor_);
+ vars["type_traits" ] = type_traits_;
+ vars["name" ] = name;
+ vars["constant_name"] = FieldConstantName(descriptor_);
+ vars["default" ] = DefaultValue(descriptor_);
+ vars["field_type" ] = SimpleItoa(static_cast<int>(descriptor_->type()));
+ vars["packed" ] = descriptor_->options().packed() ? "true" : "false";
+ vars["scope" ] = scope;
+
+ if (descriptor_->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
+ // We need to declare a global string which will contain the default value.
+ // We cannot declare it at class scope because that would require exposing
+ // it in the header which would be annoying for other reasons. So we
+ // replace :: with _ in the name and declare it as a global.
+ string global_name = StringReplace(name, "::", "_", true);
+ vars["global_name"] = global_name;
+ printer->Print(vars,
+ "const ::std::string $global_name$_default($default$);\n");
+
+ // Update the default to refer to the string global.
+ vars["default"] = global_name + "_default";
+ }
+
+ // Likewise, class members need to declare the field constant variable.
+ if (descriptor_->extension_scope() != NULL) {
+ printer->Print(vars,
+ "#ifndef _MSC_VER\n"
+ "const int $scope$$constant_name$;\n"
+ "#endif\n");
+ }
+
+ printer->Print(vars,
+ "::google::protobuf::internal::ExtensionIdentifier< $extendee$,\n"
+ " ::google::protobuf::internal::$type_traits$, $field_type$, $packed$ >\n"
+ " $name$($constant_name$, $default$);\n");
+}
+
+void ExtensionGenerator::GenerateRegistration(io::Printer* printer) {
+ map<string, string> vars;
+ vars["extendee" ] = ExtendeeClassName(descriptor_);
+ vars["number" ] = SimpleItoa(descriptor_->number());
+ vars["field_type" ] = SimpleItoa(static_cast<int>(descriptor_->type()));
+ vars["is_repeated"] = descriptor_->is_repeated() ? "true" : "false";
+ vars["is_packed" ] = (descriptor_->is_repeated() &&
+ descriptor_->options().packed())
+ ? "true" : "false";
+
+ switch (descriptor_->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_ENUM:
+ printer->Print(vars,
+ "::google::protobuf::internal::ExtensionSet::RegisterEnumExtension(\n"
+ " &$extendee$::default_instance(),\n"
+ " $number$, $field_type$, $is_repeated$, $is_packed$,\n");
+ printer->Print(
+ " &$type$_IsValid);\n",
+ "type", ClassName(descriptor_->enum_type(), true));
+ break;
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ printer->Print(vars,
+ "::google::protobuf::internal::ExtensionSet::RegisterMessageExtension(\n"
+ " &$extendee$::default_instance(),\n"
+ " $number$, $field_type$, $is_repeated$, $is_packed$,\n");
+ printer->Print(
+ " &$type$::default_instance());\n",
+ "type", ClassName(descriptor_->message_type(), true));
+ break;
+ default:
+ printer->Print(vars,
+ "::google::protobuf::internal::ExtensionSet::RegisterExtension(\n"
+ " &$extendee$::default_instance(),\n"
+ " $number$, $field_type$, $is_repeated$, $is_packed$);\n");
+ break;
+ }
+}
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_extension.h b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_extension.h
new file mode 100644
index 00000000000..82c7983c3af
--- /dev/null
+++ b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_extension.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: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_EXTENSION_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_EXTENSION_H__
+
+#include <string>
+#include <google/protobuf/stubs/common.h>
+#include "google/protobuf/compiler/cpp/cpp_options.h"
+
+namespace google {
+namespace protobuf {
+ class FieldDescriptor; // descriptor.h
+ namespace io {
+ class Printer; // printer.h
+ }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+// Generates code for an extension, which may be within the scope of some
+// message or may be at file scope. This is much simpler than FieldGenerator
+// since extensions are just simple identifiers with interesting types.
+class ExtensionGenerator {
+ public:
+ // See generator.cc for the meaning of dllexport_decl.
+ explicit ExtensionGenerator(const FieldDescriptor* desycriptor,
+ const Options& options);
+ ~ExtensionGenerator();
+
+ // Header stuff.
+ void GenerateDeclaration(io::Printer* printer);
+
+ // Source file stuff.
+ void GenerateDefinition(io::Printer* printer);
+
+ // Generate code to register the extension.
+ void GenerateRegistration(io::Printer* printer);
+
+ private:
+ const FieldDescriptor* descriptor_;
+ string type_traits_;
+ Options options_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator);
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__
diff --git a/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_field.cc b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_field.cc
new file mode 100644
index 00000000000..f10fb0ddc4d
--- /dev/null
+++ b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_field.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.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include "google/protobuf/compiler/cpp/cpp_field.h"
+#include <memory>
+
+#include "google/protobuf/compiler/cpp/cpp_helpers.h"
+#include "google/protobuf/compiler/cpp/cpp_primitive_field.h"
+#include "google/protobuf/compiler/cpp/cpp_string_field.h"
+#include "google/protobuf/compiler/cpp/cpp_enum_field.h"
+#include "google/protobuf/compiler/cpp/cpp_message_field.h"
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/stubs/common.h>
+#include "google/protobuf/stubs/strutil.h"
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+using internal::WireFormat;
+
+void SetCommonFieldVariables(const FieldDescriptor* descriptor,
+ map<string, string>* variables,
+ const Options& options) {
+ (*variables)["name"] = FieldName(descriptor);
+ (*variables)["index"] = SimpleItoa(descriptor->index());
+ (*variables)["number"] = SimpleItoa(descriptor->number());
+ (*variables)["classname"] = ClassName(FieldScope(descriptor), false);
+ (*variables)["declared_type"] = DeclaredTypeMethodName(descriptor->type());
+
+ (*variables)["tag_size"] = SimpleItoa(
+ WireFormat::TagSize(descriptor->number(), descriptor->type()));
+ (*variables)["deprecation"] = descriptor->options().deprecated()
+ ? " PROTOBUF_DEPRECATED" : "";
+
+ (*variables)["cppget"] = "Get";
+}
+
+void SetCommonOneofFieldVariables(const FieldDescriptor* descriptor,
+ map<string, string>* variables) {
+ (*variables)["oneof_prefix"] = descriptor->containing_oneof()->name() + "_.";
+ (*variables)["oneof_name"] = descriptor->containing_oneof()->name();
+}
+
+FieldGenerator::~FieldGenerator() {}
+
+void FieldGenerator::
+GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const {
+ // Reaching here indicates a bug. Cases are:
+ // - This FieldGenerator should support packing, but this method should be
+ // overridden.
+ // - This FieldGenerator doesn't support packing, and this method should
+ // never have been called.
+ GOOGLE_LOG(FATAL) << "GenerateMergeFromCodedStreamWithPacking() "
+ << "called on field generator that does not support packing.";
+
+}
+
+FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor,
+ const Options& options)
+ : descriptor_(descriptor),
+ field_generators_(
+ new scoped_ptr<FieldGenerator>[descriptor->field_count()]) {
+ // Construct all the FieldGenerators.
+ for (int i = 0; i < descriptor->field_count(); i++) {
+ field_generators_[i].reset(MakeGenerator(descriptor->field(i), options));
+ }
+}
+
+FieldGenerator* FieldGeneratorMap::MakeGenerator(const FieldDescriptor* field,
+ const Options& options) {
+ if (field->is_repeated()) {
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return new RepeatedMessageFieldGenerator(field, options);
+ case FieldDescriptor::CPPTYPE_STRING:
+ switch (field->options().ctype()) {
+ default: // RepeatedStringFieldGenerator handles unknown ctypes.
+ case FieldOptions::STRING:
+ return new RepeatedStringFieldGenerator(field, options);
+ }
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return new RepeatedEnumFieldGenerator(field, options);
+ default:
+ return new RepeatedPrimitiveFieldGenerator(field, options);
+ }
+ } else if (field->containing_oneof()) {
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return new MessageOneofFieldGenerator(field, options);
+ case FieldDescriptor::CPPTYPE_STRING:
+ switch (field->options().ctype()) {
+ default: // StringOneofFieldGenerator handles unknown ctypes.
+ case FieldOptions::STRING:
+ return new StringOneofFieldGenerator(field, options);
+ }
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return new EnumOneofFieldGenerator(field, options);
+ default:
+ return new PrimitiveOneofFieldGenerator(field, options);
+ }
+ } else {
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return new MessageFieldGenerator(field, options);
+ case FieldDescriptor::CPPTYPE_STRING:
+ switch (field->options().ctype()) {
+ default: // StringFieldGenerator handles unknown ctypes.
+ case FieldOptions::STRING:
+ return new StringFieldGenerator(field, options);
+ }
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return new EnumFieldGenerator(field, options);
+ default:
+ return new PrimitiveFieldGenerator(field, options);
+ }
+ }
+}
+
+FieldGeneratorMap::~FieldGeneratorMap() {}
+
+const FieldGenerator& FieldGeneratorMap::get(
+ const FieldDescriptor* field) const {
+ GOOGLE_CHECK_EQ(field->containing_type(), descriptor_);
+ return *field_generators_[field->index()];
+}
+
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_field.h b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_field.h
new file mode 100644
index 00000000000..9bdd370e486
--- /dev/null
+++ b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_field.h
@@ -0,0 +1,185 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_FIELD_H__
+
+#include <map>
+#include <memory>
+#include <string>
+
+#include <google/protobuf/descriptor.h>
+#include "google/protobuf/compiler/cpp/cpp_options.h"
+
+namespace google {
+namespace protobuf {
+ namespace io {
+ class Printer; // printer.h
+ }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+// Helper function: set variables in the map that are the same for all
+// field code generators.
+// ['name', 'index', 'number', 'classname', 'declared_type', 'tag_size',
+// 'deprecation'].
+void SetCommonFieldVariables(const FieldDescriptor* descriptor,
+ map<string, string>* variables,
+ const Options& options);
+
+void SetCommonOneofFieldVariables(const FieldDescriptor* descriptor,
+ map<string, string>* variables);
+
+class FieldGenerator {
+ public:
+ FieldGenerator() {}
+ virtual ~FieldGenerator();
+
+ // Generate lines of code declaring members fields of the message class
+ // needed to represent this field. These are placed inside the message
+ // class.
+ virtual void GeneratePrivateMembers(io::Printer* printer) const = 0;
+
+ // Generate static default variable for this field. These are placed inside
+ // the message class. Most field types don't need this, so the default
+ // implementation is empty.
+ virtual void GenerateStaticMembers(io::Printer* printer) const {}
+
+ // Generate prototypes for all of the accessor functions related to this
+ // field. These are placed inside the class definition.
+ virtual void GenerateAccessorDeclarations(io::Printer* printer) const = 0;
+
+ // Generate inline definitions of accessor functions for this field.
+ // These are placed inside the header after all class definitions.
+ virtual void GenerateInlineAccessorDefinitions(
+ io::Printer* printer) const = 0;
+
+ // Generate definitions of accessors that aren't inlined. These are
+ // placed somewhere in the .cc file.
+ // Most field types don't need this, so the default implementation is empty.
+ virtual void GenerateNonInlineAccessorDefinitions(
+ io::Printer* printer) const {}
+
+ // Generate lines of code (statements, not declarations) which clear the
+ // field. This is used to define the clear_$name$() method as well as
+ // the Clear() method for the whole message.
+ virtual void GenerateClearingCode(io::Printer* printer) const = 0;
+
+ // Generate lines of code (statements, not declarations) which merges the
+ // contents of the field from the current message to the target message,
+ // which is stored in the generated code variable "from".
+ // This is used to fill in the MergeFrom method for the whole message.
+ // Details of this usage can be found in message.cc under the
+ // GenerateMergeFrom method.
+ virtual void GenerateMergingCode(io::Printer* printer) const = 0;
+
+ // Generate lines of code (statements, not declarations) which swaps
+ // this field and the corresponding field of another message, which
+ // is stored in the generated code variable "other". This is used to
+ // define the Swap method. Details of usage can be found in
+ // message.cc under the GenerateSwap method.
+ virtual void GenerateSwappingCode(io::Printer* printer) const = 0;
+
+ // Generate initialization code for private members declared by
+ // GeneratePrivateMembers(). These go into the message class's SharedCtor()
+ // method, invoked by each of the generated constructors.
+ virtual void GenerateConstructorCode(io::Printer* printer) const = 0;
+
+ // Generate any code that needs to go in the class's SharedDtor() method,
+ // invoked by the destructor.
+ // Most field types don't need this, so the default implementation is empty.
+ virtual void GenerateDestructorCode(io::Printer* printer) const {}
+
+ // Generate code that allocates the fields's default instance.
+ virtual void GenerateDefaultInstanceAllocator(io::Printer* printer) const {}
+
+ // Generate code that should be run when ShutdownProtobufLibrary() is called,
+ // to delete all dynamically-allocated objects.
+ virtual void GenerateShutdownCode(io::Printer* printer) const {}
+
+ // Generate lines to decode this field, which will be placed inside the
+ // message's MergeFromCodedStream() method.
+ virtual void GenerateMergeFromCodedStream(io::Printer* printer) const = 0;
+
+ // Generate lines to decode this field from a packed value, which will be
+ // placed inside the message's MergeFromCodedStream() method.
+ virtual void GenerateMergeFromCodedStreamWithPacking(io::Printer* printer)
+ const;
+
+ // Generate lines to serialize this field, which are placed within the
+ // message's SerializeWithCachedSizes() method.
+ virtual void GenerateSerializeWithCachedSizes(io::Printer* printer) const = 0;
+
+ // Generate lines to serialize this field directly to the array "target",
+ // which are placed within the message's SerializeWithCachedSizesToArray()
+ // method. This must also advance "target" past the written bytes.
+ virtual void GenerateSerializeWithCachedSizesToArray(
+ io::Printer* printer) const = 0;
+
+ // Generate lines to compute the serialized size of this field, which
+ // are placed in the message's ByteSize() method.
+ virtual void GenerateByteSize(io::Printer* printer) const = 0;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGenerator);
+};
+
+// Convenience class which constructs FieldGenerators for a Descriptor.
+class FieldGeneratorMap {
+ public:
+ explicit FieldGeneratorMap(const Descriptor* descriptor, const Options& options);
+ ~FieldGeneratorMap();
+
+ const FieldGenerator& get(const FieldDescriptor* field) const;
+
+ private:
+ const Descriptor* descriptor_;
+ scoped_array<scoped_ptr<FieldGenerator> > field_generators_;
+
+ static FieldGenerator* MakeGenerator(const FieldDescriptor* field,
+ const Options& options);
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap);
+};
+
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_FIELD_H__
diff --git a/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_helpers.cc b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_helpers.cc
new file mode 100644
index 00000000000..6d0e3f78725
--- /dev/null
+++ b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_helpers.cc
@@ -0,0 +1,494 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 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 <limits>
+#include <map>
+#include <vector>
+#include <google/protobuf/stubs/hash.h>
+
+#include "google/protobuf/compiler/cpp/cpp_helpers.h"
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/stubs/common.h>
+#include "google/protobuf/stubs/strutil.h"
+#include <google/protobuf/stubs/substitute.h>
+
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+namespace {
+
+string DotsToUnderscores(const string& name) {
+ return StringReplace(name, ".", "_", true);
+}
+
+string DotsToColons(const string& name) {
+ return StringReplace(name, ".", "::", true);
+}
+
+const char* const kKeywordList[] = {
+ "and", "and_eq", "asm", "auto", "bitand", "bitor", "bool", "break", "case",
+ "catch", "char", "class", "compl", "const", "const_cast", "continue",
+ "default", "delete", "do", "double", "dynamic_cast", "else", "enum",
+ "explicit", "extern", "false", "float", "for", "friend", "goto", "if",
+ "inline", "int", "long", "mutable", "namespace", "new", "not", "not_eq",
+ "operator", "or", "or_eq", "private", "protected", "public", "register",
+ "reinterpret_cast", "return", "short", "signed", "sizeof", "static",
+ "static_cast", "struct", "switch", "template", "this", "throw", "true", "try",
+ "typedef", "typeid", "typename", "union", "unsigned", "using", "virtual",
+ "void", "volatile", "wchar_t", "while", "xor", "xor_eq"
+};
+
+hash_set<string> MakeKeywordsMap() {
+ hash_set<string> result;
+ for (int i = 0; i < GOOGLE_ARRAYSIZE(kKeywordList); i++) {
+ result.insert(kKeywordList[i]);
+ }
+ return result;
+}
+
+hash_set<string> kKeywords = MakeKeywordsMap();
+
+// Returns whether the provided descriptor has an extension. This includes its
+// nested types.
+bool HasExtension(const Descriptor* descriptor) {
+ if (descriptor->extension_count() > 0) {
+ return true;
+ }
+ for (int i = 0; i < descriptor->nested_type_count(); ++i) {
+ if (HasExtension(descriptor->nested_type(i))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+} // namespace
+
+string UnderscoresToCamelCase(const 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') {
+ // Capital letters are left as-is.
+ result += input[i];
+ cap_next_letter = false;
+ } else if ('0' <= input[i] && input[i] <= '9') {
+ result += input[i];
+ cap_next_letter = true;
+ } else {
+ cap_next_letter = true;
+ }
+ }
+ return result;
+}
+
+const char kThickSeparator[] =
+ "// ===================================================================\n";
+const char kThinSeparator[] =
+ "// -------------------------------------------------------------------\n";
+
+string ClassName(const Descriptor* descriptor, bool qualified) {
+
+ // Find "outer", the descriptor of the top-level message in which
+ // "descriptor" is embedded.
+ const Descriptor* outer = descriptor;
+ while (outer->containing_type() != NULL) outer = outer->containing_type();
+
+ const string& outer_name = outer->full_name();
+ string inner_name = descriptor->full_name().substr(outer_name.size());
+
+ if (qualified) {
+ return "::" + DotsToColons(outer_name) + DotsToUnderscores(inner_name);
+ } else {
+ return outer->name() + DotsToUnderscores(inner_name);
+ }
+}
+
+string ClassName(const EnumDescriptor* enum_descriptor, bool qualified) {
+ if (enum_descriptor->containing_type() == NULL) {
+ if (qualified) {
+ return "::" + DotsToColons(enum_descriptor->full_name());
+ } else {
+ return enum_descriptor->name();
+ }
+ } else {
+ string result = ClassName(enum_descriptor->containing_type(), qualified);
+ result += '_';
+ result += enum_descriptor->name();
+ return result;
+ }
+}
+
+
+string SuperClassName(const Descriptor* descriptor) {
+ return HasDescriptorMethods(descriptor->file()) ?
+ "::google::protobuf::Message" : "::google::protobuf::MessageLite";
+}
+
+string FieldName(const FieldDescriptor* field) {
+ string result = field->name();
+ LowerString(&result);
+ if (kKeywords.count(result) > 0) {
+ result.append("_");
+ }
+ return result;
+}
+
+string FieldConstantName(const FieldDescriptor *field) {
+ string field_name = UnderscoresToCamelCase(field->name(), true);
+ string result = "k" + field_name + "FieldNumber";
+
+ if (!field->is_extension() &&
+ field->containing_type()->FindFieldByCamelcaseName(
+ field->camelcase_name()) != field) {
+ // This field's camelcase name is not unique. As a hack, add the field
+ // number to the constant name. This makes the constant rather useless,
+ // but what can we do?
+ result += "_" + SimpleItoa(field->number());
+ }
+
+ return result;
+}
+
+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.
+ return ClassName(field->message_type(), true);
+}
+
+string StripProto(const string& filename) {
+ if (HasSuffixString(filename, ".protodevel")) {
+ return StripSuffixString(filename, ".protodevel");
+ } else {
+ return StripSuffixString(filename, ".proto");
+ }
+}
+
+const char* PrimitiveTypeName(FieldDescriptor::CppType type) {
+ switch (type) {
+ case FieldDescriptor::CPPTYPE_INT32 : return "::google::protobuf::int32";
+ case FieldDescriptor::CPPTYPE_INT64 : return "::google::protobuf::int64";
+ case FieldDescriptor::CPPTYPE_UINT32 : return "::google::protobuf::uint32";
+ case FieldDescriptor::CPPTYPE_UINT64 : return "::google::protobuf::uint64";
+ case FieldDescriptor::CPPTYPE_DOUBLE : return "double";
+ case FieldDescriptor::CPPTYPE_FLOAT : return "float";
+ case FieldDescriptor::CPPTYPE_BOOL : return "bool";
+ case FieldDescriptor::CPPTYPE_ENUM : return "int";
+ case FieldDescriptor::CPPTYPE_STRING : return "::std::string";
+ case FieldDescriptor::CPPTYPE_MESSAGE: return NULL;
+
+ // No default because we want the compiler to complain if any new
+ // CppTypes are added.
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return NULL;
+}
+
+const char* DeclaredTypeMethodName(FieldDescriptor::Type type) {
+ switch (type) {
+ case FieldDescriptor::TYPE_INT32 : return "Int32";
+ case FieldDescriptor::TYPE_INT64 : return "Int64";
+ case FieldDescriptor::TYPE_UINT32 : return "UInt32";
+ case FieldDescriptor::TYPE_UINT64 : return "UInt64";
+ case FieldDescriptor::TYPE_SINT32 : return "SInt32";
+ case FieldDescriptor::TYPE_SINT64 : return "SInt64";
+ case FieldDescriptor::TYPE_FIXED32 : return "Fixed32";
+ case FieldDescriptor::TYPE_FIXED64 : return "Fixed64";
+ case FieldDescriptor::TYPE_SFIXED32: return "SFixed32";
+ case FieldDescriptor::TYPE_SFIXED64: return "SFixed64";
+ case FieldDescriptor::TYPE_FLOAT : return "Float";
+ case FieldDescriptor::TYPE_DOUBLE : return "Double";
+
+ case FieldDescriptor::TYPE_BOOL : return "Bool";
+ case FieldDescriptor::TYPE_ENUM : return "Enum";
+
+ case FieldDescriptor::TYPE_STRING : return "String";
+ case FieldDescriptor::TYPE_BYTES : return "Bytes";
+ case FieldDescriptor::TYPE_GROUP : return "Group";
+ case FieldDescriptor::TYPE_MESSAGE : return "Message";
+
+ // No default because we want the compiler to complain if any new
+ // types are added.
+ }
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return "";
+}
+
+string Int32ToString(int number) {
+ // gcc rejects the decimal form of kint32min.
+ if (number == kint32min) {
+ GOOGLE_COMPILE_ASSERT(kint32min == (~0x7fffffff), kint32min_value_error);
+ return "(~0x7fffffff)";
+ } else {
+ return SimpleItoa(number);
+ }
+}
+
+string Int64ToString(int64 number) {
+ // gcc rejects the decimal form of kint64min
+ if (number == kint64min) {
+ // Make sure we are in a 2's complement system.
+ GOOGLE_COMPILE_ASSERT(kint64min == GOOGLE_LONGLONG(~0x7fffffffffffffff),
+ kint64min_value_error);
+ return "GOOGLE_LONGLONG(~0x7fffffffffffffff)";
+ }
+ return "GOOGLE_LONGLONG(" + SimpleItoa(number) + ")";
+}
+
+string DefaultValue(const FieldDescriptor* field) {
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ return Int32ToString(field->default_value_int32());
+ case FieldDescriptor::CPPTYPE_UINT32:
+ return SimpleItoa(field->default_value_uint32()) + "u";
+ case FieldDescriptor::CPPTYPE_INT64:
+ return Int64ToString(field->default_value_int64());
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return "GOOGLE_ULONGLONG(" + SimpleItoa(field->default_value_uint64())+ ")";
+ case FieldDescriptor::CPPTYPE_DOUBLE: {
+ double value = field->default_value_double();
+ if (value == numeric_limits<double>::infinity()) {
+ return "::google::protobuf::internal::Infinity()";
+ } else if (value == -numeric_limits<double>::infinity()) {
+ return "-::google::protobuf::internal::Infinity()";
+ } else if (value != value) {
+ return "::google::protobuf::internal::NaN()";
+ } else {
+ return SimpleDtoa(value);
+ }
+ }
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ {
+ float value = field->default_value_float();
+ if (value == numeric_limits<float>::infinity()) {
+ return "static_cast<float>(::google::protobuf::internal::Infinity())";
+ } else if (value == -numeric_limits<float>::infinity()) {
+ return "static_cast<float>(-::google::protobuf::internal::Infinity())";
+ } else if (value != value) {
+ return "static_cast<float>(::google::protobuf::internal::NaN())";
+ } else {
+ string float_value = SimpleFtoa(value);
+ // If floating point value contains a period (.) or an exponent
+ // (either E or e), then append suffix 'f' to make it a float
+ // literal.
+ if (float_value.find_first_of(".eE") != string::npos) {
+ float_value.push_back('f');
+ }
+ return float_value;
+ }
+ }
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return field->default_value_bool() ? "true" : "false";
+ case FieldDescriptor::CPPTYPE_ENUM:
+ // Lazy: Generate a static_cast because we don't have a helper function
+ // that constructs the full name of an enum value.
+ return strings::Substitute(
+ "static_cast< $0 >($1)",
+ ClassName(field->enum_type(), true),
+ Int32ToString(field->default_value_enum()->number()));
+ case FieldDescriptor::CPPTYPE_STRING:
+ return "\"" + EscapeTrigraphs(
+ CEscape(field->default_value_string())) +
+ "\"";
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return FieldMessageTypeName(field) + "::default_instance()";
+ }
+ // Can't actually get here; make compiler happy. (We could add a default
+ // case above but then we wouldn't get the nice compiler warning when a
+ // new type is added.)
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return "";
+}
+
+// Convert a file name into a valid identifier.
+string FilenameIdentifier(const string& filename) {
+ string result;
+ for (int i = 0; i < filename.size(); i++) {
+ if (ascii_isalnum(filename[i])) {
+ result.push_back(filename[i]);
+ } else {
+ // Not alphanumeric. To avoid any possibility of name conflicts we
+ // use the hex code for the character.
+ result.push_back('_');
+ char buffer[kFastToBufferSize];
+ result.append(FastHexToBuffer(static_cast<uint8>(filename[i]), buffer));
+ }
+ }
+ return result;
+}
+
+// Return the name of the AddDescriptors() function for a given file.
+string GlobalAddDescriptorsName(const string& filename) {
+ return "protobuf_AddDesc_" + FilenameIdentifier(filename);
+}
+
+// Return the name of the AssignDescriptors() function for a given file.
+string GlobalAssignDescriptorsName(const string& filename) {
+ return "protobuf_AssignDesc_" + FilenameIdentifier(filename);
+}
+
+// Return the name of the ShutdownFile() function for a given file.
+string GlobalShutdownFileName(const string& filename) {
+ return "protobuf_ShutdownFile_" + FilenameIdentifier(filename);
+}
+
+// Return the qualified C++ name for a file level symbol.
+string QualifiedFileLevelSymbol(const string& package, const string& name) {
+ if (package.empty()) {
+ return StrCat("::", name);
+ }
+ return StrCat("::", DotsToColons(package), "::", name);
+}
+
+// Escape C++ trigraphs by escaping question marks to \?
+string EscapeTrigraphs(const string& to_escape) {
+ return StringReplace(to_escape, "?", "\\?", true);
+}
+
+// Escaped function name to eliminate naming conflict.
+string SafeFunctionName(const Descriptor* descriptor,
+ const FieldDescriptor* field,
+ const string& prefix) {
+ // Do not use FieldName() since it will escape keywords.
+ string name = field->name();
+ LowerString(&name);
+ string function_name = prefix + name;
+ if (descriptor->FindFieldByName(function_name)) {
+ // Single underscore will also make it conflicting with the private data
+ // member. We use double underscore to escape function names.
+ function_name.append("__");
+ } else if (kKeywords.count(name) > 0) {
+ // If the field name is a keyword, we append the underscore back to keep it
+ // consistent with other function names.
+ function_name.append("_");
+ }
+ return function_name;
+}
+
+bool StaticInitializersForced(const FileDescriptor* file) {
+ if (HasDescriptorMethods(file) || file->extension_count() > 0) {
+ return true;
+ }
+ for (int i = 0; i < file->message_type_count(); ++i) {
+ if (HasExtension(file->message_type(i))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void PrintHandlingOptionalStaticInitializers(
+ const FileDescriptor* file, io::Printer* printer,
+ const char* with_static_init, const char* without_static_init,
+ const char* var1, const string& val1,
+ const char* var2, const string& val2) {
+ map<string, string> vars;
+ if (var1) {
+ vars[var1] = val1;
+ }
+ if (var2) {
+ vars[var2] = val2;
+ }
+ PrintHandlingOptionalStaticInitializers(
+ vars, file, printer, with_static_init, without_static_init);
+}
+
+void PrintHandlingOptionalStaticInitializers(
+ const map<string, string>& vars, const FileDescriptor* file,
+ io::Printer* printer, const char* with_static_init,
+ const char* without_static_init) {
+ if (StaticInitializersForced(file)) {
+ printer->Print(vars, with_static_init);
+ } else {
+ printer->Print(vars, (string(
+ "#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n") +
+ without_static_init +
+ "#else\n" +
+ with_static_init +
+ "#endif\n").c_str());
+ }
+}
+
+
+static bool HasEnumDefinitions(const Descriptor* message_type) {
+ if (message_type->enum_type_count() > 0) return true;
+ for (int i = 0; i < message_type->nested_type_count(); ++i) {
+ if (HasEnumDefinitions(message_type->nested_type(i))) return true;
+ }
+ return false;
+}
+
+bool HasEnumDefinitions(const FileDescriptor* file) {
+ if (file->enum_type_count() > 0) return true;
+ for (int i = 0; i < file->message_type_count(); ++i) {
+ if (HasEnumDefinitions(file->message_type(i))) return true;
+ }
+ return false;
+}
+
+bool IsStringOrMessage(const FieldDescriptor* field) {
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ case FieldDescriptor::CPPTYPE_INT64:
+ case FieldDescriptor::CPPTYPE_UINT32:
+ case FieldDescriptor::CPPTYPE_UINT64:
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ case FieldDescriptor::CPPTYPE_BOOL:
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return false;
+ case FieldDescriptor::CPPTYPE_STRING:
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return true;
+ }
+
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return false;
+}
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_helpers.h b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_helpers.h
new file mode 100644
index 00000000000..5d30240c77b
--- /dev/null
+++ b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_helpers.h
@@ -0,0 +1,206 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__
+
+#include <map>
+#include <string>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+
+namespace google {
+namespace protobuf {
+
+namespace io {
+class Printer;
+}
+
+namespace compiler {
+namespace cpp {
+
+// Commonly-used separator comments. Thick is a line of '=', thin is a line
+// of '-'.
+extern const char kThickSeparator[];
+extern const char kThinSeparator[];
+
+// Returns the non-nested type name for the given type. If "qualified" is
+// true, prefix the type with the full namespace. For example, if you had:
+// package foo.bar;
+// message Baz { message Qux {} }
+// Then the qualified ClassName for Qux would be:
+// ::foo::bar::Baz_Qux
+// While the non-qualified version would be:
+// Baz_Qux
+string ClassName(const Descriptor* descriptor, bool qualified);
+string ClassName(const EnumDescriptor* enum_descriptor, bool qualified);
+
+string SuperClassName(const Descriptor* descriptor);
+
+// Get the (unqualified) name that should be used for this field in C++ code.
+// The name is coerced to lower-case to emulate proto1 behavior. People
+// should be using lowercase-with-underscores style for proto field names
+// anyway, so normally this just returns field->name().
+string FieldName(const FieldDescriptor* field);
+
+// Get the unqualified name that should be used for a field's field
+// number constant.
+string FieldConstantName(const FieldDescriptor *field);
+
+// Returns the scope where the field was defined (for extensions, this is
+// different from the message type to which the field applies).
+inline const Descriptor* FieldScope(const FieldDescriptor* field) {
+ return field->is_extension() ?
+ field->extension_scope() : field->containing_type();
+}
+
+// Returns the fully-qualified type name field->message_type(). Usually this
+// is just ClassName(field->message_type(), true);
+string FieldMessageTypeName(const FieldDescriptor* field);
+
+// Strips ".proto" or ".protodevel" from the end of a filename.
+string StripProto(const string& filename);
+
+// Get the C++ type name for a primitive type (e.g. "double", "::google::protobuf::int32", etc.).
+// Note: non-built-in type names will be qualified, meaning they will start
+// with a ::. If you are using the type as a template parameter, you will
+// need to insure there is a space between the < and the ::, because the
+// ridiculous C++ standard defines "<:" to be a synonym for "[".
+const char* PrimitiveTypeName(FieldDescriptor::CppType type);
+
+// Get the declared type name in CamelCase format, as is used e.g. for the
+// methods of WireFormat. For example, TYPE_INT32 becomes "Int32".
+const char* DeclaredTypeMethodName(FieldDescriptor::Type type);
+
+// Return the code that evaluates to the number when compiled.
+string Int32ToString(int number);
+
+// Return the code that evaluates to the number when compiled.
+string Int64ToString(int64 number);
+
+// Get code that evaluates to the field's default value.
+string DefaultValue(const FieldDescriptor* field);
+
+// Convert a file name into a valid identifier.
+string FilenameIdentifier(const string& filename);
+
+// Return the name of the AddDescriptors() function for a given file.
+string GlobalAddDescriptorsName(const string& filename);
+
+// Return the name of the AssignDescriptors() function for a given file.
+string GlobalAssignDescriptorsName(const string& filename);
+
+// Return the qualified C++ name for a file level symbol.
+string QualifiedFileLevelSymbol(const string& package, const string& name);
+
+// Return the name of the ShutdownFile() function for a given file.
+string GlobalShutdownFileName(const string& filename);
+
+// Escape C++ trigraphs by escaping question marks to \?
+string EscapeTrigraphs(const string& to_escape);
+
+// Escaped function name to eliminate naming conflict.
+string SafeFunctionName(const Descriptor* descriptor,
+ const FieldDescriptor* field,
+ const string& prefix);
+
+// Do message classes in this file use UnknownFieldSet?
+// Otherwise, messages will store unknown fields in a string
+inline bool UseUnknownFieldSet(const FileDescriptor* file) {
+ return file->options().optimize_for() != FileOptions::LITE_RUNTIME;
+}
+
+
+// Does this file have any enum type definitions?
+bool HasEnumDefinitions(const FileDescriptor* file);
+
+// Does this file have generated parsing, serialization, and other
+// standard methods for which reflection-based fallback implementations exist?
+inline bool HasGeneratedMethods(const FileDescriptor* file) {
+ return file->options().optimize_for() != FileOptions::CODE_SIZE;
+}
+
+// Do message classes in this file have descriptor and reflection methods?
+inline bool HasDescriptorMethods(const FileDescriptor* file) {
+ return 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 &&
+ file->options().optimize_for() != FileOptions::LITE_RUNTIME &&
+ file->options().cc_generic_services();
+}
+
+// Should string fields in this file verify that their contents are UTF-8?
+inline bool HasUtf8Verification(const FileDescriptor* file) {
+ return file->options().optimize_for() != FileOptions::LITE_RUNTIME;
+}
+
+// Should we generate a separate, super-optimized code path for serializing to
+// flat arrays? We don't do this in Lite mode because we'd rather reduce code
+// size.
+inline bool HasFastArraySerialization(const FileDescriptor* file) {
+ return file->options().optimize_for() == FileOptions::SPEED;
+}
+
+// Returns whether we have to generate code with static initializers.
+bool StaticInitializersForced(const FileDescriptor* file);
+
+// Prints 'with_static_init' if static initializers have to be used for the
+// provided file. Otherwise emits both 'with_static_init' and
+// 'without_static_init' using #ifdef.
+void PrintHandlingOptionalStaticInitializers(
+ const FileDescriptor* file, io::Printer* printer,
+ const char* with_static_init, const char* without_static_init,
+ const char* var1 = NULL, const string& val1 = "",
+ const char* var2 = NULL, const string& val2 = "");
+
+void PrintHandlingOptionalStaticInitializers(
+ const map<string, string>& vars, const FileDescriptor* file,
+ io::Printer* printer, const char* with_static_init,
+ const char* without_static_init);
+
+
+// Returns true if the field's CPPTYPE is string or message.
+bool IsStringOrMessage(const FieldDescriptor* field);
+
+string UnderscoresToCamelCase(const string& input, bool cap_next_letter);
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__
diff --git a/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_message.cc b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_message.cc
new file mode 100644
index 00000000000..f153e948387
--- /dev/null
+++ b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_message.cc
@@ -0,0 +1,2645 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 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 <map>
+#include <memory>
+#include <set>
+#include <utility>
+#include <vector>
+#include "google/protobuf/compiler/cpp/cpp_message.h"
+#include "google/protobuf/compiler/cpp/cpp_field.h"
+#include "google/protobuf/compiler/cpp/cpp_enum.h"
+#include "google/protobuf/compiler/cpp/cpp_extension.h"
+#include "google/protobuf/compiler/cpp/cpp_helpers.h"
+#include "google/protobuf/stubs/strutil.h"
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/wire_format.h>
+#include <google/protobuf/descriptor.pb.h>
+
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+using internal::WireFormat;
+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();
+ printer->Print("// $def$\n",
+ "def", def.substr(0, def.find_first_of('\n')));
+}
+
+struct FieldOrderingByNumber {
+ inline bool operator()(const FieldDescriptor* a,
+ const FieldDescriptor* b) const {
+ return a->number() < b->number();
+ }
+};
+
+// Sort the fields of the given Descriptor by number into a new[]'d array
+// and return it.
+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;
+}
+
+// Functor for sorting extension ranges by their "start" field number.
+struct ExtensionRangeSorter {
+ bool operator()(const Descriptor::ExtensionRange* left,
+ const Descriptor::ExtensionRange* right) const {
+ return left->start < right->start;
+ }
+};
+
+// Returns true if the "required" restriction check should be ignored for the
+// given field.
+inline static bool ShouldIgnoreRequiredFieldCheck(
+ const FieldDescriptor* field) {
+ return false;
+}
+
+// Returns true if the message type has any required fields. If it doesn't,
+// we can optimize out calls to its IsInitialized() method.
+//
+// already_seen is used to avoid checking the same type multiple times
+// (and also to protect against recursion).
+static bool HasRequiredFields(
+ const Descriptor* type,
+ hash_set<const Descriptor*>* already_seen) {
+ if (already_seen->count(type) > 0) {
+ // Since the first occurrence of a required field causes the whole
+ // function to return true, we can assume that if the type is already
+ // in the cache it didn't have any required fields.
+ return false;
+ }
+ already_seen->insert(type);
+
+ // If the type has extensions, an extension with message type could contain
+ // required fields, so we have to be conservative and assume such an
+ // extension exists.
+ if (type->extension_range_count() > 0) return true;
+
+ for (int i = 0; i < type->field_count(); i++) {
+ const FieldDescriptor* field = type->field(i);
+ if (field->is_required()) {
+ return true;
+ }
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
+ !ShouldIgnoreRequiredFieldCheck(field)) {
+ if (HasRequiredFields(field->message_type(), already_seen)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+static bool HasRequiredFields(const Descriptor* type) {
+ hash_set<const Descriptor*> already_seen;
+ return HasRequiredFields(type, &already_seen);
+}
+
+// This returns an estimate of the compiler's alignment for the field. This
+// can't guarantee to be correct because the generated code could be compiled on
+// different systems with different alignment rules. The estimates below assume
+// 64-bit pointers.
+int EstimateAlignmentSize(const FieldDescriptor* field) {
+ if (field == NULL) return 0;
+ if (field->is_repeated()) return 8;
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return 1;
+
+ case FieldDescriptor::CPPTYPE_INT32:
+ case FieldDescriptor::CPPTYPE_UINT32:
+ case FieldDescriptor::CPPTYPE_ENUM:
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ return 4;
+
+ case FieldDescriptor::CPPTYPE_INT64:
+ case FieldDescriptor::CPPTYPE_UINT64:
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ case FieldDescriptor::CPPTYPE_STRING:
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return 8;
+ }
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return -1; // Make compiler happy.
+}
+
+// FieldGroup is just a helper for OptimizePadding below. It holds a vector of
+// fields that are grouped together because they have compatible alignment, and
+// a preferred location in the final field ordering.
+class FieldGroup {
+ public:
+ FieldGroup()
+ : preferred_location_(0) {}
+
+ // A group with a single field.
+ FieldGroup(float preferred_location, const FieldDescriptor* field)
+ : preferred_location_(preferred_location),
+ fields_(1, field) {}
+
+ // Append the fields in 'other' to this group.
+ void Append(const FieldGroup& other) {
+ if (other.fields_.empty()) {
+ return;
+ }
+ // Preferred location is the average among all the fields, so we weight by
+ // the number of fields on each FieldGroup object.
+ preferred_location_ =
+ (preferred_location_ * fields_.size() +
+ (other.preferred_location_ * other.fields_.size())) /
+ (fields_.size() + other.fields_.size());
+ fields_.insert(fields_.end(), other.fields_.begin(), other.fields_.end());
+ }
+
+ void SetPreferredLocation(float location) { preferred_location_ = location; }
+ const vector<const FieldDescriptor*>& fields() const { return fields_; }
+
+ // FieldGroup objects sort by their preferred location.
+ bool operator<(const FieldGroup& other) const {
+ return preferred_location_ < other.preferred_location_;
+ }
+
+ private:
+ // "preferred_location_" is an estimate of where this group should go in the
+ // final list of fields. We compute this by taking the average index of each
+ // field in this group in the original ordering of fields. This is very
+ // approximate, but should put this group close to where its member fields
+ // originally went.
+ float preferred_location_;
+ vector<const FieldDescriptor*> fields_;
+ // We rely on the default copy constructor and operator= so this type can be
+ // used in a vector.
+};
+
+// Reorder 'fields' so that if the fields are output into a c++ class in the new
+// order, the alignment padding is minimized. We try to do this while keeping
+// each field as close as possible to its original position so that we don't
+// reduce cache locality much for function that access each field in order.
+void OptimizePadding(vector<const FieldDescriptor*>* fields) {
+ // First divide fields into those that align to 1 byte, 4 bytes or 8 bytes.
+ vector<FieldGroup> aligned_to_1, aligned_to_4, aligned_to_8;
+ for (int i = 0; i < fields->size(); ++i) {
+ switch (EstimateAlignmentSize((*fields)[i])) {
+ case 1: aligned_to_1.push_back(FieldGroup(i, (*fields)[i])); break;
+ case 4: aligned_to_4.push_back(FieldGroup(i, (*fields)[i])); break;
+ case 8: aligned_to_8.push_back(FieldGroup(i, (*fields)[i])); break;
+ default:
+ GOOGLE_LOG(FATAL) << "Unknown alignment size.";
+ }
+ }
+
+ // Now group fields aligned to 1 byte into sets of 4, and treat those like a
+ // single field aligned to 4 bytes.
+ for (int i = 0; i < aligned_to_1.size(); i += 4) {
+ FieldGroup field_group;
+ for (int j = i; j < aligned_to_1.size() && j < i + 4; ++j) {
+ field_group.Append(aligned_to_1[j]);
+ }
+ aligned_to_4.push_back(field_group);
+ }
+ // Sort by preferred location to keep fields as close to their original
+ // location as possible. Using stable_sort ensures that the output is
+ // consistent across runs.
+ stable_sort(aligned_to_4.begin(), aligned_to_4.end());
+
+ // Now group fields aligned to 4 bytes (or the 4-field groups created above)
+ // into pairs, and treat those like a single field aligned to 8 bytes.
+ for (int i = 0; i < aligned_to_4.size(); i += 2) {
+ FieldGroup field_group;
+ for (int j = i; j < aligned_to_4.size() && j < i + 2; ++j) {
+ field_group.Append(aligned_to_4[j]);
+ }
+ if (i == aligned_to_4.size() - 1) {
+ // Move incomplete 4-byte block to the end.
+ field_group.SetPreferredLocation(fields->size() + 1);
+ }
+ aligned_to_8.push_back(field_group);
+ }
+ // Sort by preferred location.
+ stable_sort(aligned_to_8.begin(), aligned_to_8.end());
+
+ // Now pull out all the FieldDescriptors in order.
+ fields->clear();
+ for (int i = 0; i < aligned_to_8.size(); ++i) {
+ fields->insert(fields->end(),
+ aligned_to_8[i].fields().begin(),
+ aligned_to_8[i].fields().end());
+ }
+}
+
+string MessageTypeProtoName(const FieldDescriptor* field) {
+ return field->message_type()->full_name();
+}
+
+}
+
+// ===================================================================
+
+MessageGenerator::MessageGenerator(const Descriptor* descriptor,
+ const Options& options)
+ : descriptor_(descriptor),
+ classname_(ClassName(descriptor, false)),
+ options_(options),
+ field_generators_(descriptor, options),
+ nested_generators_(new scoped_ptr<
+ MessageGenerator>[descriptor->nested_type_count()]),
+ enum_generators_(
+ new scoped_ptr<EnumGenerator>[descriptor->enum_type_count()]),
+ extension_generators_(new scoped_ptr<
+ ExtensionGenerator>[descriptor->extension_count()]) {
+
+ for (int i = 0; i < descriptor->nested_type_count(); i++) {
+ nested_generators_[i].reset(
+ new MessageGenerator(descriptor->nested_type(i), options));
+ }
+
+ for (int i = 0; i < descriptor->enum_type_count(); i++) {
+ enum_generators_[i].reset(
+ new EnumGenerator(descriptor->enum_type(i), options));
+ }
+
+ for (int i = 0; i < descriptor->extension_count(); i++) {
+ extension_generators_[i].reset(
+ new ExtensionGenerator(descriptor->extension(i), options));
+ }
+}
+
+MessageGenerator::~MessageGenerator() {}
+
+void MessageGenerator::
+GenerateForwardDeclaration(io::Printer* printer) {
+ printer->Print("class $classname$;\n",
+ "classname", classname_);
+
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ nested_generators_[i]->GenerateForwardDeclaration(printer);
+ }
+}
+
+void MessageGenerator::
+GenerateEnumDefinitions(io::Printer* printer) {
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ nested_generators_[i]->GenerateEnumDefinitions(printer);
+ }
+
+ for (int i = 0; i < descriptor_->enum_type_count(); i++) {
+ enum_generators_[i]->GenerateDefinition(printer);
+ }
+}
+
+void MessageGenerator::
+GenerateGetEnumDescriptorSpecializations(io::Printer* printer) {
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ nested_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
+ }
+ for (int i = 0; i < descriptor_->enum_type_count(); i++) {
+ enum_generators_[i]->GenerateGetEnumDescriptorSpecializations(printer);
+ }
+}
+
+void MessageGenerator::
+GenerateFieldAccessorDeclarations(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_);
+ vars["constant_name"] = FieldConstantName(field);
+
+ if (field->is_repeated()) {
+ printer->Print(vars, "inline int $name$_size() const$deprecation$;\n");
+ } else {
+ printer->Print(vars, "inline bool has_$name$() const$deprecation$;\n");
+ }
+
+ printer->Print(vars, "inline void clear_$name$()$deprecation$;\n");
+ printer->Print(vars, "static const int $constant_name$ = $number$;\n");
+
+ // Generate type-specific accessor declarations.
+ field_generators_.get(field).GenerateAccessorDeclarations(printer);
+
+ printer->Print("\n");
+ }
+
+ if (descriptor_->extension_range_count() > 0) {
+ // Generate accessors for extensions. We just call a macro located in
+ // extension_set.h since the accessors about 80 lines of static code.
+ printer->Print(
+ "GOOGLE_PROTOBUF_EXTENSION_ACCESSORS($classname$)\n",
+ "classname", classname_);
+ }
+
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ printer->Print(
+ "inline $camel_oneof_name$Case $oneof_name$_case() const;\n",
+ "camel_oneof_name",
+ UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true),
+ "oneof_name", descriptor_->oneof_decl(i)->name());
+ }
+}
+
+void MessageGenerator::
+GenerateFieldAccessorDefinitions(io::Printer* printer) {
+ printer->Print("// $classname$\n\n", "classname", classname_);
+
+ 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_);
+
+ // Generate has_$name$() or $name$_size().
+ if (field->is_repeated()) {
+ printer->Print(vars,
+ "inline int $classname$::$name$_size() const {\n"
+ " return $name$_.size();\n"
+ "}\n");
+ } else if (field->containing_oneof()) {
+ // Singular field in a oneof
+ 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"
+ "inline void $classname$::set_has_$name$() {\n"
+ " _oneof_case_[$oneof_index$] = k$field_name$;\n"
+ "}\n");
+ } else {
+ // Singular field.
+ 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"
+ );
+ }
+
+ // 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 (!field->is_repeated()) {
+ printer->Print(vars,
+ "clear_has_$name$();\n");
+ }
+ }
+
+ printer->Outdent();
+ printer->Print("}\n");
+
+ // Generate type-specific accessors.
+ field_generators_.get(field).GenerateInlineAccessorDefinitions(printer);
+
+ 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_;
+ printer->Print(
+ vars,
+ "inline bool $classname$::has_$oneof_name$() {\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");
+ }
+}
+
+// Helper for the code that emits the Clear() method.
+static bool CanClearByZeroing(const FieldDescriptor* field) {
+ if (field->is_repeated() || field->is_extension()) return false;
+ switch (field->cpp_type()) {
+ case internal::WireFormatLite::CPPTYPE_ENUM:
+ return field->default_value_enum()->number() == 0;
+ case internal::WireFormatLite::CPPTYPE_INT32:
+ return field->default_value_int32() == 0;
+ case internal::WireFormatLite::CPPTYPE_INT64:
+ return field->default_value_int64() == 0;
+ case internal::WireFormatLite::CPPTYPE_UINT32:
+ return field->default_value_uint32() == 0;
+ case internal::WireFormatLite::CPPTYPE_UINT64:
+ return field->default_value_uint64() == 0;
+ case internal::WireFormatLite::CPPTYPE_FLOAT:
+ return field->default_value_float() == 0;
+ case internal::WireFormatLite::CPPTYPE_DOUBLE:
+ return field->default_value_double() == 0;
+ case internal::WireFormatLite::CPPTYPE_BOOL:
+ return field->default_value_bool() == false;
+ default:
+ return false;
+ }
+}
+
+void MessageGenerator::
+GenerateClassDefinition(io::Printer* printer) {
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ nested_generators_[i]->GenerateClassDefinition(printer);
+ printer->Print("\n");
+ printer->Print(kThinSeparator);
+ printer->Print("\n");
+ }
+
+ map<string, string> vars;
+ vars["classname"] = classname_;
+ vars["field_count"] = SimpleItoa(descriptor_->field_count());
+ vars["oneof_decl_count"] = SimpleItoa(descriptor_->oneof_decl_count());
+ if (options_.dllexport_decl.empty()) {
+ vars["dllexport"] = "";
+ } else {
+ vars["dllexport"] = options_.dllexport_decl + " ";
+ }
+ vars["superclass"] = SuperClassName(descriptor_);
+
+ printer->Print(vars,
+ "class $dllexport$$classname$ : public $superclass$ {\n"
+ " public:\n");
+ printer->Indent();
+
+ printer->Print(vars,
+ "$classname$();\n"
+ "virtual ~$classname$();\n"
+ "\n"
+ "$classname$(const $classname$& from);\n"
+ "\n"
+ "inline $classname$& operator=(const $classname$& from) {\n"
+ " CopyFrom(from);\n"
+ " return *this;\n"
+ "}\n"
+ "\n");
+
+ if (UseUnknownFieldSet(descriptor_->file())) {
+ printer->Print(
+ "inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {\n"
+ " return _unknown_fields_;\n"
+ "}\n"
+ "\n"
+ "inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {\n"
+ " return &_unknown_fields_;\n"
+ "}\n"
+ "\n");
+ } else {
+ printer->Print(
+ "inline const ::std::string& unknown_fields() const {\n"
+ " return _unknown_fields_;\n"
+ "}\n"
+ "\n"
+ "inline ::std::string* mutable_unknown_fields() {\n"
+ " return &_unknown_fields_;\n"
+ "}\n"
+ "\n");
+ }
+
+ // Only generate this member if it's not disabled.
+ if (HasDescriptorMethods(descriptor_->file()) &&
+ !descriptor_->options().no_standard_descriptor_accessor()) {
+ printer->Print(vars,
+ "static const ::google::protobuf::Descriptor* descriptor();\n");
+ }
+
+ printer->Print(vars,
+ "static const $classname$& default_instance();\n"
+ "\n");
+
+ // Generate enum values for every field in oneofs. One list is generated for
+ // each oneof with an additional *_NOT_SET value.
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ printer->Print(
+ "enum $camel_oneof_name$Case {\n",
+ "camel_oneof_name",
+ UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true));
+ printer->Indent();
+ for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
+ printer->Print(
+ "k$field_name$ = $field_number$,\n",
+ "field_name",
+ UnderscoresToCamelCase(
+ descriptor_->oneof_decl(i)->field(j)->name(), true),
+ "field_number",
+ SimpleItoa(descriptor_->oneof_decl(i)->field(j)->number()));
+ }
+ printer->Print(
+ "$cap_oneof_name$_NOT_SET = 0,\n",
+ "cap_oneof_name",
+ ToUpper(descriptor_->oneof_decl(i)->name()));
+ printer->Outdent();
+ printer->Print(
+ "};\n"
+ "\n");
+ }
+
+ if (!StaticInitializersForced(descriptor_->file())) {
+ printer->Print(vars,
+ "#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER\n"
+ "// Returns the internal default instance pointer. This function can\n"
+ "// return NULL thus should not be used by the user. This is intended\n"
+ "// for Protobuf internal code. Please use default_instance() declared\n"
+ "// above instead.\n"
+ "static inline const $classname$* internal_default_instance() {\n"
+ " return default_instance_;\n"
+ "}\n"
+ "#endif\n"
+ "\n");
+ }
+
+
+ printer->Print(vars,
+ "void Swap($classname$* other);\n"
+ "\n"
+ "// implements Message ----------------------------------------------\n"
+ "\n"
+ "$classname$* New() const;\n");
+
+ if (HasGeneratedMethods(descriptor_->file())) {
+ if (HasDescriptorMethods(descriptor_->file())) {
+ printer->Print(vars,
+ "void CopyFrom(const ::google::protobuf::Message& from);\n"
+ "void MergeFrom(const ::google::protobuf::Message& from);\n");
+ } else {
+ printer->Print(vars,
+ "void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from);\n");
+ }
+
+ printer->Print(vars,
+ "void CopyFrom(const $classname$& from);\n"
+ "void MergeFrom(const $classname$& from);\n"
+ "void Clear();\n"
+ "bool IsInitialized() const;\n"
+ "\n"
+ "int ByteSize() const;\n"
+ "bool MergePartialFromCodedStream(\n"
+ " ::google::protobuf::io::CodedInputStream* input);\n"
+ "void SerializeWithCachedSizes(\n"
+ " ::google::protobuf::io::CodedOutputStream* output) const;\n");
+ // DiscardUnknownFields() is implemented in message.cc using reflections. We
+ // need to implement this function in generated code for messages.
+ if (!UseUnknownFieldSet(descriptor_->file())) {
+ printer->Print(
+ "void DiscardUnknownFields();\n");
+ }
+ if (HasFastArraySerialization(descriptor_->file())) {
+ printer->Print(
+ "::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;\n");
+ }
+ }
+
+ // Check all FieldDescriptors including those in oneofs to estimate
+ // whether ::std::string is likely to be used, and depending on that
+ // estimate, set uses_string_ to true or false. That contols
+ // whether to force initialization of empty_string_ in SharedCtor().
+ // It's often advantageous to do so to keep "is empty_string_
+ // inited?" code from appearing all over the place.
+ vector<const FieldDescriptor*> descriptors;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ descriptors.push_back(descriptor_->field(i));
+ }
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
+ descriptors.push_back(descriptor_->oneof_decl(i)->field(j));
+ }
+ }
+ uses_string_ = false;
+ for (int i = 0; i < descriptors.size(); i++) {
+ const FieldDescriptor* field = descriptors[i];
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
+ switch (field->options().ctype()) {
+ default: uses_string_ = true; break;
+ }
+ }
+ }
+
+ printer->Print(
+ "int GetCachedSize() const { return _cached_size_; }\n"
+ "private:\n"
+ "void SharedCtor();\n"
+ "void SharedDtor();\n"
+ "void SetCachedSize(int size) const;\n"
+ "public:\n");
+
+ if (HasDescriptorMethods(descriptor_->file())) {
+ printer->Print(
+ "::google::protobuf::Metadata GetMetadata() const;\n"
+ "\n");
+ } else {
+ printer->Print(
+ "::std::string GetTypeName() const;\n"
+ "\n");
+ }
+
+ printer->Print(
+ "// nested types ----------------------------------------------------\n"
+ "\n");
+
+ // Import all nested message classes into this class's scope with typedefs.
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ const Descriptor* nested_type = descriptor_->nested_type(i);
+ printer->Print("typedef $nested_full_name$ $nested_name$;\n",
+ "nested_name", nested_type->name(),
+ "nested_full_name", ClassName(nested_type, false));
+ }
+
+ if (descriptor_->nested_type_count() > 0) {
+ printer->Print("\n");
+ }
+
+ // Import all nested enums and their values into this class's scope with
+ // typedefs and constants.
+ for (int i = 0; i < descriptor_->enum_type_count(); i++) {
+ enum_generators_[i]->GenerateSymbolImports(printer);
+ printer->Print("\n");
+ }
+
+ printer->Print(
+ "// accessors -------------------------------------------------------\n"
+ "\n");
+
+ // Generate accessor methods for all fields.
+ GenerateFieldAccessorDeclarations(printer);
+
+ // Declare extension identifiers.
+ for (int i = 0; i < descriptor_->extension_count(); i++) {
+ extension_generators_[i]->GenerateDeclaration(printer);
+ }
+
+
+ printer->Print(
+ "// @@protoc_insertion_point(class_scope:$full_name$)\n",
+ "full_name", descriptor_->full_name());
+
+ // Generate private members.
+ printer->Outdent();
+ printer->Print(" private:\n");
+ printer->Indent();
+
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ if (!descriptor_->field(i)->is_repeated()) {
+ printer->Print(
+ "inline void set_has_$name$();\n",
+ "name", FieldName(descriptor_->field(i)));
+ if (!descriptor_->field(i)->containing_oneof()) {
+ printer->Print(
+ "inline void clear_has_$name$();\n",
+ "name", FieldName(descriptor_->field(i)));
+ }
+ }
+ }
+ printer->Print("\n");
+
+ // Generate oneof function declarations
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ printer->Print(
+ "inline bool has_$oneof_name$();\n"
+ "void clear_$oneof_name$();\n"
+ "inline void clear_has_$oneof_name$();\n\n",
+ "oneof_name", descriptor_->oneof_decl(i)->name());
+ }
+
+ // Prepare decls for _cached_size_ and _has_bits_. Their position in the
+ // output will be determined later.
+
+ bool need_to_emit_cached_size = true;
+ // TODO(kenton): Make _cached_size_ an atomic<int> when C++ supports it.
+ const string cached_size_decl = "mutable int _cached_size_;\n";
+
+ // TODO(jieluo) - Optimize _has_bits_ for repeated and oneof fields.
+ size_t sizeof_has_bits = (descriptor_->field_count() + 31) / 32 * 4;
+ if (descriptor_->field_count() == 0) {
+ // Zero-size arrays aren't technically allowed, and MSVC in particular
+ // doesn't like them. We still need to declare these arrays to make
+ // other code compile. Since this is an uncommon case, we'll just declare
+ // them with size 1 and waste some space. Oh well.
+ sizeof_has_bits = 4;
+ }
+ const string has_bits_decl = sizeof_has_bits == 0 ? "" :
+ "::google::protobuf::uint32 _has_bits_[" + SimpleItoa(sizeof_has_bits / 4) + "];\n";
+
+
+ // To minimize padding, data members are divided into three sections:
+ // (1) members assumed to align to 8 bytes
+ // (2) members corresponding to message fields, re-ordered to optimize
+ // alignment.
+ // (3) members assumed to align to 4 bytes.
+
+ // Members assumed to align to 8 bytes:
+
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(
+ "::google::protobuf::internal::ExtensionSet _extensions_;\n"
+ "\n");
+ }
+
+ if (UseUnknownFieldSet(descriptor_->file())) {
+ printer->Print(
+ "::google::protobuf::UnknownFieldSet _unknown_fields_;\n"
+ "\n");
+ } else {
+ printer->Print(
+ "::std::string _unknown_fields_;\n"
+ "\n");
+ }
+
+ // _has_bits_ is frequently accessed, so to reduce code size and improve
+ // speed, it should be close to the start of the object. But, try not to
+ // waste space:_has_bits_ by itself always makes sense if its size is a
+ // multiple of 8, but, otherwise, maybe _has_bits_ and cached_size_ together
+ // will work well.
+ printer->Print(has_bits_decl.c_str());
+ if ((sizeof_has_bits % 8) != 0) {
+ printer->Print(cached_size_decl.c_str());
+ need_to_emit_cached_size = false;
+ }
+
+ // Field members:
+
+ // List fields which doesn't belong to any oneof
+ vector<const FieldDescriptor*> fields;
+ hash_map<string, int> fieldname_to_chunk;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ if (!descriptor_->field(i)->containing_oneof()) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ fields.push_back(field);
+ fieldname_to_chunk[FieldName(field)] = i / 8;
+ }
+ }
+ OptimizePadding(&fields);
+ // Emit some private and static members
+ runs_of_fields_ = vector< vector<string> >(1);
+ for (int i = 0; i < fields.size(); ++i) {
+ const FieldDescriptor* field = fields[i];
+ const FieldGenerator& generator = field_generators_.get(field);
+ generator.GenerateStaticMembers(printer);
+ generator.GeneratePrivateMembers(printer);
+ if (CanClearByZeroing(field)) {
+ const string& fieldname = FieldName(field);
+ if (!runs_of_fields_.back().empty() &&
+ (fieldname_to_chunk[runs_of_fields_.back().back()] !=
+ fieldname_to_chunk[fieldname])) {
+ runs_of_fields_.push_back(vector<string>());
+ }
+ runs_of_fields_.back().push_back(fieldname);
+ } else if (!runs_of_fields_.back().empty()) {
+ runs_of_fields_.push_back(vector<string>());
+ }
+ }
+
+ // For each oneof generate a union
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ printer->Print(
+ "union $camel_oneof_name$Union {\n",
+ "camel_oneof_name",
+ UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true));
+ printer->Indent();
+ for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
+ field_generators_.get(descriptor_->oneof_decl(i)->
+ field(j)).GeneratePrivateMembers(printer);
+ }
+ printer->Outdent();
+ printer->Print(
+ "} $oneof_name$_;\n",
+ "oneof_name", descriptor_->oneof_decl(i)->name());
+ for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
+ field_generators_.get(descriptor_->oneof_decl(i)->
+ field(j)).GenerateStaticMembers(printer);
+ }
+ }
+
+ // Members assumed to align to 4 bytes:
+
+ if (need_to_emit_cached_size) {
+ printer->Print(cached_size_decl.c_str());
+ need_to_emit_cached_size = false;
+ }
+
+ // Generate _oneof_case_.
+ if (descriptor_->oneof_decl_count() > 0) {
+ printer->Print(vars,
+ "::google::protobuf::uint32 _oneof_case_[$oneof_decl_count$];\n"
+ "\n");
+ }
+
+ // Declare AddDescriptors(), BuildDescriptors(), and ShutdownFile() as
+ // friends so that they can access private static variables like
+ // default_instance_ and reflection_.
+ PrintHandlingOptionalStaticInitializers(
+ descriptor_->file(), printer,
+ // With static initializers.
+ "friend void $dllexport_decl$ $adddescriptorsname$();\n",
+ // Without.
+ "friend void $dllexport_decl$ $adddescriptorsname$_impl();\n",
+ // Vars.
+ "dllexport_decl", options_.dllexport_decl,
+ "adddescriptorsname",
+ GlobalAddDescriptorsName(descriptor_->file()->name()));
+
+ printer->Print(
+ "friend void $assigndescriptorsname$();\n"
+ "friend void $shutdownfilename$();\n"
+ "\n",
+ "assigndescriptorsname",
+ GlobalAssignDescriptorsName(descriptor_->file()->name()),
+ "shutdownfilename", GlobalShutdownFileName(descriptor_->file()->name()));
+
+ printer->Print(
+ "void InitAsDefaultInstance();\n"
+ "static $classname$* default_instance_;\n",
+ "classname", classname_);
+
+ printer->Outdent();
+ printer->Print(vars, "};");
+ GOOGLE_DCHECK(!need_to_emit_cached_size);
+}
+
+void MessageGenerator::
+GenerateInlineMethods(io::Printer* printer) {
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ nested_generators_[i]->GenerateInlineMethods(printer);
+ printer->Print(kThinSeparator);
+ printer->Print("\n");
+ }
+
+ GenerateFieldAccessorDefinitions(printer);
+
+ // Generate oneof_case() functions.
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ map<string, string> vars;
+ vars["class_name"] = classname_;
+ vars["camel_oneof_name"] = UnderscoresToCamelCase(
+ descriptor_->oneof_decl(i)->name(), true);
+ vars["oneof_name"] = descriptor_->oneof_decl(i)->name();
+ vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
+ printer->Print(
+ vars,
+ "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"
+ "}\n");
+ }
+}
+
+void MessageGenerator::
+GenerateDescriptorDeclarations(io::Printer* printer) {
+ printer->Print(
+ "const ::google::protobuf::Descriptor* $name$_descriptor_ = NULL;\n"
+ "const ::google::protobuf::internal::GeneratedMessageReflection*\n"
+ " $name$_reflection_ = NULL;\n",
+ "name", classname_);
+
+ // Generate oneof default instance for reflection usage.
+ if (descriptor_->oneof_decl_count() > 0) {
+ printer->Print("struct $name$OneofInstance {\n",
+ "name", classname_);
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
+ const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
+ printer->Print(" ");
+ if (IsStringOrMessage(field)) {
+ printer->Print("const ");
+ }
+ field_generators_.get(field).GeneratePrivateMembers(printer);
+ }
+ }
+
+ printer->Print("}* $name$_default_oneof_instance_ = NULL;\n",
+ "name", classname_);
+ }
+
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ nested_generators_[i]->GenerateDescriptorDeclarations(printer);
+ }
+
+ for (int i = 0; i < descriptor_->enum_type_count(); i++) {
+ printer->Print(
+ "const ::google::protobuf::EnumDescriptor* $name$_descriptor_ = NULL;\n",
+ "name", ClassName(descriptor_->enum_type(i), false));
+ }
+}
+
+void MessageGenerator::
+GenerateDescriptorInitializer(io::Printer* printer, int index) {
+ // TODO(kenton): Passing the index to this method is redundant; just use
+ // descriptor_->index() instead.
+ map<string, string> vars;
+ vars["classname"] = classname_;
+ vars["index"] = SimpleItoa(index);
+
+ // Obtain the descriptor from the parent's descriptor.
+ if (descriptor_->containing_type() == NULL) {
+ printer->Print(vars,
+ "$classname$_descriptor_ = file->message_type($index$);\n");
+ } else {
+ vars["parent"] = ClassName(descriptor_->containing_type(), false);
+ printer->Print(vars,
+ "$classname$_descriptor_ = "
+ "$parent$_descriptor_->nested_type($index$);\n");
+ }
+
+ // Generate the offsets.
+ GenerateOffsets(printer);
+
+ // Construct the reflection object.
+ printer->Print(vars,
+ "$classname$_reflection_ =\n"
+ " new ::google::protobuf::internal::GeneratedMessageReflection(\n"
+ " $classname$_descriptor_,\n"
+ " $classname$::default_instance_,\n"
+ " $classname$_offsets_,\n"
+ " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, _has_bits_[0]),\n"
+ " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
+ "$classname$, _unknown_fields_),\n");
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(vars,
+ " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
+ "$classname$, _extensions_),\n");
+ } else {
+ // No extensions.
+ printer->Print(vars,
+ " -1,\n");
+ }
+
+ if (descriptor_->oneof_decl_count() > 0) {
+ printer->Print(vars,
+ " $classname$_default_oneof_instance_,\n"
+ " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET("
+ "$classname$, _oneof_case_[0]),\n");
+ }
+
+ printer->Print(
+ " ::google::protobuf::DescriptorPool::generated_pool(),\n");
+ printer->Print(vars,
+ " ::google::protobuf::MessageFactory::generated_factory(),\n");
+ printer->Print(vars,
+ " sizeof($classname$));\n");
+
+ // Handle nested types.
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ nested_generators_[i]->GenerateDescriptorInitializer(printer, i);
+ }
+
+ for (int i = 0; i < descriptor_->enum_type_count(); i++) {
+ enum_generators_[i]->GenerateDescriptorInitializer(printer, i);
+ }
+}
+
+void MessageGenerator::
+GenerateTypeRegistrations(io::Printer* printer) {
+ // Register this message type with the message factory.
+ printer->Print(
+ "::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n"
+ " $classname$_descriptor_, &$classname$::default_instance());\n",
+ "classname", classname_);
+
+ // Handle nested types.
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ nested_generators_[i]->GenerateTypeRegistrations(printer);
+ }
+}
+
+void MessageGenerator::
+GenerateDefaultInstanceAllocator(io::Printer* printer) {
+ // Construct the default instances of all fields, as they will be used
+ // when creating the default instance of the entire message.
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ field_generators_.get(descriptor_->field(i))
+ .GenerateDefaultInstanceAllocator(printer);
+ }
+
+ // Construct the default instance. We can't call InitAsDefaultInstance() yet
+ // because we need to make sure all default instances that this one might
+ // depend on are constructed first.
+ printer->Print(
+ "$classname$::default_instance_ = new $classname$();\n",
+ "classname", classname_);
+
+ if ((descriptor_->oneof_decl_count() > 0) &&
+ HasDescriptorMethods(descriptor_->file())) {
+ printer->Print(
+ "$classname$_default_oneof_instance_ = new $classname$OneofInstance;\n",
+ "classname", classname_);
+ }
+
+ // Handle nested types.
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ nested_generators_[i]->GenerateDefaultInstanceAllocator(printer);
+ }
+
+}
+
+void MessageGenerator::
+GenerateDefaultInstanceInitializer(io::Printer* printer) {
+ printer->Print(
+ "$classname$::default_instance_->InitAsDefaultInstance();\n",
+ "classname", classname_);
+
+ // Register extensions.
+ for (int i = 0; i < descriptor_->extension_count(); i++) {
+ extension_generators_[i]->GenerateRegistration(printer);
+ }
+
+ // Handle nested types.
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ nested_generators_[i]->GenerateDefaultInstanceInitializer(printer);
+ }
+}
+
+void MessageGenerator::
+GenerateShutdownCode(io::Printer* printer) {
+ printer->Print(
+ "delete $classname$::default_instance_;\n",
+ "classname", classname_);
+
+ if (HasDescriptorMethods(descriptor_->file())) {
+ if (descriptor_->oneof_decl_count() > 0) {
+ printer->Print(
+ "delete $classname$_default_oneof_instance_;\n",
+ "classname", classname_);
+ }
+ printer->Print(
+ "delete $classname$_reflection_;\n",
+ "classname", classname_);
+ }
+
+ // Handle default instances of fields.
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ field_generators_.get(descriptor_->field(i))
+ .GenerateShutdownCode(printer);
+ }
+
+ // Handle nested types.
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ nested_generators_[i]->GenerateShutdownCode(printer);
+ }
+}
+
+void MessageGenerator::
+GenerateClassMethods(io::Printer* printer) {
+ for (int i = 0; i < descriptor_->enum_type_count(); i++) {
+ enum_generators_[i]->GenerateMethods(printer);
+ }
+
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ nested_generators_[i]->GenerateClassMethods(printer);
+ printer->Print("\n");
+ printer->Print(kThinSeparator);
+ printer->Print("\n");
+ }
+
+ // Generate non-inline field definitions.
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ field_generators_.get(descriptor_->field(i))
+ .GenerateNonInlineAccessorDefinitions(printer);
+ }
+
+ // Generate field number constants.
+ printer->Print("#ifndef _MSC_VER\n");
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor *field = descriptor_->field(i);
+ printer->Print(
+ "const int $classname$::$constant_name$;\n",
+ "classname", ClassName(FieldScope(field), false),
+ "constant_name", FieldConstantName(field));
+ }
+ printer->Print(
+ "#endif // !_MSC_VER\n"
+ "\n");
+
+ // Define extension identifiers.
+ for (int i = 0; i < descriptor_->extension_count(); i++) {
+ extension_generators_[i]->GenerateDefinition(printer);
+ }
+
+ GenerateStructors(printer);
+ printer->Print("\n");
+
+ if (descriptor_->oneof_decl_count() > 0) {
+ GenerateOneofClear(printer);
+ printer->Print("\n");
+ }
+
+ if (HasGeneratedMethods(descriptor_->file())) {
+ GenerateClear(printer);
+ printer->Print("\n");
+
+ GenerateMergeFromCodedStream(printer);
+ printer->Print("\n");
+
+ GenerateSerializeWithCachedSizes(printer);
+ printer->Print("\n");
+
+ if (HasFastArraySerialization(descriptor_->file())) {
+ GenerateSerializeWithCachedSizesToArray(printer);
+ printer->Print("\n");
+ }
+
+ GenerateByteSize(printer);
+ printer->Print("\n");
+
+ GenerateMergeFrom(printer);
+ printer->Print("\n");
+
+ GenerateCopyFrom(printer);
+ printer->Print("\n");
+
+ GenerateIsInitialized(printer);
+ printer->Print("\n");
+ }
+
+ GenerateSwap(printer);
+ printer->Print("\n");
+
+ if (HasDescriptorMethods(descriptor_->file())) {
+ printer->Print(
+ "::google::protobuf::Metadata $classname$::GetMetadata() const {\n"
+ " protobuf_AssignDescriptorsOnce();\n"
+ " ::google::protobuf::Metadata metadata;\n"
+ " metadata.descriptor = $classname$_descriptor_;\n"
+ " metadata.reflection = $classname$_reflection_;\n"
+ " return metadata;\n"
+ "}\n"
+ "\n",
+ "classname", classname_);
+ } else {
+ printer->Print(
+ "::std::string $classname$::GetTypeName() const {\n"
+ " return \"$type_name$\";\n"
+ "}\n"
+ "\n",
+ "classname", classname_,
+ "type_name", descriptor_->full_name());
+ }
+
+}
+
+void MessageGenerator::
+GenerateOffsets(io::Printer* printer) {
+ printer->Print(
+ "static const int $classname$_offsets_[$field_count$] = {\n",
+ "classname", classname_,
+ "field_count", SimpleItoa(max(
+ 1, descriptor_->field_count() + descriptor_->oneof_decl_count())));
+ printer->Indent();
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ if (field->containing_oneof()) {
+ printer->Print(
+ "PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET("
+ "$classname$_default_oneof_instance_, $name$_),\n",
+ "classname", classname_,
+ "name", FieldName(field));
+ } else {
+ printer->Print(
+ "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, "
+ "$name$_),\n",
+ "classname", classname_,
+ "name", FieldName(field));
+ }
+ }
+
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
+ printer->Print(
+ "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, $name$_),\n",
+ "classname", classname_,
+ "name", oneof->name());
+ }
+
+ printer->Outdent();
+ printer->Print("};\n");
+}
+
+void MessageGenerator::
+GenerateSharedConstructorCode(io::Printer* printer) {
+ printer->Print(
+ "void $classname$::SharedCtor() {\n",
+ "classname", classname_);
+ printer->Indent();
+
+ printer->Print(StrCat(
+ uses_string_ ? "::google::protobuf::internal::GetEmptyString();\n" : "",
+ "_cached_size_ = 0;\n").c_str());
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ if (!descriptor_->field(i)->containing_oneof()) {
+ field_generators_.get(descriptor_->field(i))
+ .GenerateConstructorCode(printer);
+ }
+ }
+
+ printer->Print(
+ "::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
+
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ printer->Print(
+ "clear_has_$oneof_name$();\n",
+ "oneof_name", descriptor_->oneof_decl(i)->name());
+ }
+
+ printer->Outdent();
+ printer->Print("}\n\n");
+}
+
+void MessageGenerator::
+GenerateSharedDestructorCode(io::Printer* printer) {
+ printer->Print(
+ "void $classname$::SharedDtor() {\n",
+ "classname", classname_);
+ printer->Indent();
+ // Write the destructors for each field except oneof members.
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ if (!descriptor_->field(i)->containing_oneof()) {
+ field_generators_.get(descriptor_->field(i))
+ .GenerateDestructorCode(printer);
+ }
+ }
+
+ // Generate code to destruct oneofs. Clearing should do the work.
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ printer->Print(
+ "if (has_$oneof_name$()) {\n"
+ " clear_$oneof_name$();\n"
+ "}\n",
+ "oneof_name", descriptor_->oneof_decl(i)->name());
+ }
+
+ PrintHandlingOptionalStaticInitializers(
+ descriptor_->file(), printer,
+ // With static initializers.
+ "if (this != default_instance_) {\n",
+ // Without.
+ "if (this != &default_instance()) {\n");
+
+ // We need to delete all embedded messages.
+ // TODO(kenton): If we make unset messages point at default instances
+ // instead of NULL, then it would make sense to move this code into
+ // MessageFieldGenerator::GenerateDestructorCode().
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+
+ if (!field->is_repeated() &&
+ field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ // Skip oneof members
+ if (!field->containing_oneof()) {
+ printer->Print(
+ " delete $name$_;\n",
+ "name", FieldName(field));
+ }
+ }
+ }
+
+ printer->Outdent();
+ printer->Print(
+ " }\n"
+ "}\n"
+ "\n");
+}
+
+void MessageGenerator::
+GenerateStructors(io::Printer* printer) {
+ string superclass = SuperClassName(descriptor_);
+
+ // Generate the default constructor.
+ printer->Print(
+ "$classname$::$classname$()\n"
+ " : $superclass$() {\n"
+ " SharedCtor();\n"
+ " // @@protoc_insertion_point(constructor:$full_name$)\n"
+ "}\n",
+ "classname", classname_,
+ "superclass", superclass,
+ "full_name", descriptor_->full_name());
+
+ printer->Print(
+ "\n"
+ "void $classname$::InitAsDefaultInstance() {\n",
+ "classname", classname_);
+
+ // The default instance needs all of its embedded message pointers
+ // cross-linked to other default instances. We can't do this initialization
+ // in the constructor because some other default instances may not have been
+ // constructed yet at that time.
+ // TODO(kenton): Maybe all message fields (even for non-default messages)
+ // should be initialized to point at default instances rather than NULL?
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+
+ if (!field->is_repeated() &&
+ field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
+ (field->containing_oneof() == NULL ||
+ HasDescriptorMethods(descriptor_->file()))) {
+ string name;
+ if (field->containing_oneof()) {
+ name = classname_ + "_default_oneof_instance_->";
+ }
+ name += FieldName(field);
+ PrintHandlingOptionalStaticInitializers(
+ descriptor_->file(), printer,
+ // With static initializers.
+ " $name$_ = const_cast< $type$*>(&$type$::default_instance());\n",
+ // Without.
+ " $name$_ = const_cast< $type$*>(\n"
+ " $type$::internal_default_instance());\n",
+ // Vars.
+ "name", name,
+ "type", FieldMessageTypeName(field));
+ } else if (field->containing_oneof() &&
+ HasDescriptorMethods(descriptor_->file())) {
+ field_generators_.get(descriptor_->field(i))
+ .GenerateConstructorCode(printer);
+ }
+ }
+ printer->Print(
+ "}\n"
+ "\n");
+
+ // Generate the copy constructor.
+ printer->Print(
+ "$classname$::$classname$(const $classname$& from)\n"
+ " : $superclass$() {\n"
+ " SharedCtor();\n"
+ " MergeFrom(from);\n"
+ " // @@protoc_insertion_point(copy_constructor:$full_name$)\n"
+ "}\n"
+ "\n",
+ "classname", classname_,
+ "superclass", superclass,
+ "full_name", descriptor_->full_name());
+
+ // Generate the shared constructor code.
+ GenerateSharedConstructorCode(printer);
+
+ // Generate the destructor.
+ printer->Print(
+ "$classname$::~$classname$() {\n"
+ " // @@protoc_insertion_point(destructor:$full_name$)\n"
+ " SharedDtor();\n"
+ "}\n"
+ "\n",
+ "classname", classname_,
+ "full_name", descriptor_->full_name());
+
+ // Generate the shared destructor code.
+ GenerateSharedDestructorCode(printer);
+
+ // Generate SetCachedSize.
+ printer->Print(
+ "void $classname$::SetCachedSize(int size) const {\n"
+ " GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
+ " _cached_size_ = size;\n"
+ " GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
+ "}\n",
+ "classname", classname_);
+
+ // Only generate this member if it's not disabled.
+ if (HasDescriptorMethods(descriptor_->file()) &&
+ !descriptor_->options().no_standard_descriptor_accessor()) {
+ printer->Print(
+ "const ::google::protobuf::Descriptor* $classname$::descriptor() {\n"
+ " protobuf_AssignDescriptorsOnce();\n"
+ " return $classname$_descriptor_;\n"
+ "}\n"
+ "\n",
+ "classname", classname_,
+ "adddescriptorsname",
+ GlobalAddDescriptorsName(descriptor_->file()->name()));
+ }
+
+ printer->Print(
+ "const $classname$& $classname$::default_instance() {\n",
+ "classname", classname_);
+
+ PrintHandlingOptionalStaticInitializers(
+ descriptor_->file(), printer,
+ // With static initializers.
+ " if (default_instance_ == NULL) $adddescriptorsname$();\n",
+ // Without.
+ " $adddescriptorsname$();\n",
+ // Vars.
+ "adddescriptorsname",
+ GlobalAddDescriptorsName(descriptor_->file()->name()));
+
+ printer->Print(
+ " return *default_instance_;\n"
+ "}\n"
+ "\n"
+ "$classname$* $classname$::default_instance_ = NULL;\n"
+ "\n",
+ "classname", classname_);
+
+ printer->Print(
+ "$classname$* $classname$::New() const {\n"
+ " return new $classname$;\n"
+ "}\n",
+ "classname", classname_);
+
+}
+
+// Return the number of bits set in n, a non-negative integer.
+static int popcnt(uint32 n) {
+ int result = 0;
+ while (n != 0) {
+ result += (n & 1);
+ n = n / 2;
+ }
+ return result;
+}
+
+void MessageGenerator::
+GenerateClear(io::Printer* printer) {
+ printer->Print("void $classname$::Clear() {\n",
+ "classname", classname_);
+ printer->Indent();
+
+ // Step 1: Extensions
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print("_extensions_.Clear();\n");
+ }
+
+ // Step 2: Everything but extensions, repeateds, unions.
+ // These are handled in chunks of 8. The first chunk is
+ // the non-extensions-non-repeateds-non-unions in
+ // descriptor_->field(0), descriptor_->field(1), ... descriptor_->field(7),
+ // and the second chunk is the same for
+ // descriptor_->field(8), descriptor_->field(9), ... descriptor_->field(15),
+ // etc.
+ set<int> step2_indices;
+ hash_map<string, int> fieldname_to_chunk;
+ hash_map<int, string> memsets_for_chunk;
+ hash_map<int, int> memset_field_count_for_chunk;
+ hash_set<string> handled; // fields that appear anywhere in memsets_for_chunk
+ hash_map<int, uint32> fields_mask_for_chunk;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ if (!field->is_repeated() && !field->containing_oneof()) {
+ step2_indices.insert(i);
+ int chunk = i / 8;
+ fieldname_to_chunk[FieldName(field)] = chunk;
+ fields_mask_for_chunk[chunk] |= static_cast<uint32>(1) << (i % 32);
+ }
+ }
+
+ // Step 2a: Greedily seek runs of fields that can be cleared by memset-to-0.
+ // The generated code uses two macros to help it clear runs of fields:
+ // OFFSET_OF_FIELD_ computes the offset (in bytes) of a field in the Message.
+ // ZR_ zeroes a non-empty range of fields via memset.
+ const char* macros =
+ "#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char*>( \\\n"
+ " &reinterpret_cast<$classname$*>(16)->f) - \\\n"
+ " reinterpret_cast<char*>(16))\n\n"
+ "#define ZR_(first, last) do { \\\n"
+ " size_t f = OFFSET_OF_FIELD_(first); \\\n"
+ " size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \\\n"
+ " ::memset(&first, 0, n); \\\n"
+ " } while (0)\n\n";
+ for (int i = 0; i < runs_of_fields_.size(); i++) {
+ const vector<string>& run = runs_of_fields_[i];
+ if (run.size() < 2) continue;
+ const string& first_field_name = run[0];
+ const string& last_field_name = run.back();
+ int chunk = fieldname_to_chunk[run[0]];
+ memsets_for_chunk[chunk].append(
+ "ZR_(" + first_field_name + "_, " + last_field_name + "_);\n");
+ for (int j = 0; j < run.size(); j++) {
+ GOOGLE_DCHECK_EQ(chunk, fieldname_to_chunk[run[j]]);
+ handled.insert(run[j]);
+ }
+ memset_field_count_for_chunk[chunk] += run.size();
+ }
+ const bool macros_are_needed = handled.size() > 0;
+ if (macros_are_needed) {
+ printer->Outdent();
+ printer->Print(macros,
+ "classname", classname_);
+ printer->Indent();
+ }
+ // Step 2b: Finish step 2, ignoring fields handled in step 2a.
+ int last_index = -1;
+ bool chunk_block_in_progress = false;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ if (step2_indices.count(i) == 0) continue;
+ const FieldDescriptor* field = descriptor_->field(i);
+ const string fieldname = FieldName(field);
+ if (i / 8 != last_index / 8 || last_index < 0) {
+ // End previous chunk, if there was one.
+ if (chunk_block_in_progress) {
+ printer->Outdent();
+ printer->Print("}\n");
+ chunk_block_in_progress = false;
+ }
+ // Start chunk.
+ const string& memsets = memsets_for_chunk[i / 8];
+ uint32 mask = fields_mask_for_chunk[i / 8];
+ int count = popcnt(mask);
+ if (count == 1 ||
+ (count <= 4 && count == memset_field_count_for_chunk[i / 8])) {
+ // No "if" here because the chunk is trivial.
+ } else {
+ printer->Print(
+ "if (_has_bits_[$index$ / 32] & $mask$) {\n",
+ "index", SimpleItoa(i / 8 * 8),
+ "mask", SimpleItoa(mask));
+ printer->Indent();
+ chunk_block_in_progress = true;
+ }
+ printer->Print(memsets.c_str());
+ }
+ last_index = i;
+ if (handled.count(fieldname) > 0) continue;
+
+ // It's faster to just overwrite primitive types, but we should
+ // only clear strings and messages if they were set.
+ // TODO(kenton): Let the CppFieldGenerator decide this somehow.
+ bool should_check_bit =
+ field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ||
+ field->cpp_type() == FieldDescriptor::CPPTYPE_STRING;
+
+ if (should_check_bit) {
+ printer->Print("if (has_$name$()) {\n", "name", fieldname);
+ printer->Indent();
+ }
+
+ field_generators_.get(field).GenerateClearingCode(printer);
+
+ if (should_check_bit) {
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+ }
+
+ if (chunk_block_in_progress) {
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+ if (macros_are_needed) {
+ printer->Outdent();
+ printer->Print("\n#undef OFFSET_OF_FIELD_\n#undef ZR_\n\n");
+ printer->Indent();
+ }
+
+ // Step 3: Repeated fields don't use _has_bits_; emit code to clear them here.
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+
+ if (field->is_repeated()) {
+ field_generators_.get(field).GenerateClearingCode(printer);
+ }
+ }
+
+ // Step 4: Unions.
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ printer->Print(
+ "clear_$oneof_name$();\n",
+ "oneof_name", descriptor_->oneof_decl(i)->name());
+ }
+
+ // Step 5: Everything else.
+ printer->Print(
+ "::memset(_has_bits_, 0, sizeof(_has_bits_));\n");
+
+ if (UseUnknownFieldSet(descriptor_->file())) {
+ printer->Print(
+ "mutable_unknown_fields()->Clear();\n");
+ } else {
+ printer->Print(
+ "mutable_unknown_fields()->clear();\n");
+ }
+
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+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());
+ printer->Indent();
+ printer->Print(
+ "switch($oneofname$_case()) {\n",
+ "oneofname", descriptor_->oneof_decl(i)->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 k$field_name$: {\n",
+ "field_name", UnderscoresToCamelCase(field->name(), true));
+ printer->Indent();
+ // We clear only allocated objects in oneofs
+ if (!IsStringOrMessage(field)) {
+ printer->Print(
+ "// No need to clear\n");
+ } else {
+ field_generators_.get(field).GenerateClearingCode(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(descriptor_->oneof_decl(i)->name()));
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "_oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n",
+ "oneof_index", SimpleItoa(i),
+ "cap_oneof_name",
+ ToUpper(descriptor_->oneof_decl(i)->name()));
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "\n");
+ }
+}
+
+void MessageGenerator::
+GenerateSwap(io::Printer* printer) {
+ // Generate the Swap member function.
+ printer->Print("void $classname$::Swap($classname$* other) {\n",
+ "classname", classname_);
+ printer->Indent();
+ printer->Print("if (other != this) {\n");
+ printer->Indent();
+
+ if (HasGeneratedMethods(descriptor_->file())) {
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ field_generators_.get(field).GenerateSwappingCode(printer);
+ }
+
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ printer->Print(
+ "std::swap($oneof_name$_, other->$oneof_name$_);\n"
+ "std::swap(_oneof_case_[$i$], other->_oneof_case_[$i$]);\n",
+ "oneof_name", descriptor_->oneof_decl(i)->name(),
+ "i", SimpleItoa(i));
+ }
+
+ for (int i = 0; i < (descriptor_->field_count() + 31) / 32; ++i) {
+ printer->Print("std::swap(_has_bits_[$i$], other->_has_bits_[$i$]);\n",
+ "i", SimpleItoa(i));
+ }
+
+ if (UseUnknownFieldSet(descriptor_->file())) {
+ printer->Print("_unknown_fields_.Swap(&other->_unknown_fields_);\n");
+ } else {
+ printer->Print("_unknown_fields_.swap(other->_unknown_fields_);\n");
+ }
+ printer->Print("std::swap(_cached_size_, other->_cached_size_);\n");
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print("_extensions_.Swap(&other->_extensions_);\n");
+ }
+ } else {
+ printer->Print("GetReflection()->Swap(this, other);");
+ }
+
+ printer->Outdent();
+ printer->Print("}\n");
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void MessageGenerator::
+GenerateMergeFrom(io::Printer* printer) {
+ if (HasDescriptorMethods(descriptor_->file())) {
+ // Generate the generalized MergeFrom (aka that which takes in the Message
+ // base class as a parameter).
+ printer->Print(
+ "void $classname$::MergeFrom(const ::google::protobuf::Message& from) {\n"
+ " GOOGLE_CHECK_NE(&from, this);\n",
+ "classname", classname_);
+ printer->Indent();
+
+ // Cast the message to the proper type. If we find that the message is
+ // *not* of the proper type, we can still call Merge via the reflection
+ // 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"
+ "if (source == NULL) {\n"
+ " ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n"
+ "} else {\n"
+ " MergeFrom(*source);\n"
+ "}\n",
+ "classname", classname_);
+
+ printer->Outdent();
+ printer->Print("}\n\n");
+ } else {
+ // Generate CheckTypeAndMergeFrom().
+ printer->Print(
+ "void $classname$::CheckTypeAndMergeFrom(\n"
+ " const ::google::protobuf::MessageLite& from) {\n"
+ " MergeFrom(*::google::protobuf::down_cast<const $classname$*>(&from));\n"
+ "}\n"
+ "\n",
+ "classname", classname_);
+ }
+
+ // Generate the class-specific MergeFrom, which avoids the GOOGLE_CHECK and cast.
+ printer->Print(
+ "void $classname$::MergeFrom(const $classname$& from) {\n"
+ " GOOGLE_CHECK_NE(&from, this);\n",
+ "classname", classname_);
+ printer->Indent();
+
+ // Merge Repeated fields. These fields do not require a
+ // check as we can simply iterate over them.
+ for (int i = 0; i < descriptor_->field_count(); ++i) {
+ const FieldDescriptor* field = descriptor_->field(i);
+
+ if (field->is_repeated()) {
+ field_generators_.get(field).GenerateMergingCode(printer);
+ }
+ }
+
+ // Merge oneof fields. Oneof field requires oneof case check.
+ for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) {
+ printer->Print(
+ "switch (from.$oneofname$_case()) {\n",
+ "oneofname", descriptor_->oneof_decl(i)->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 k$field_name$: {\n",
+ "field_name", UnderscoresToCamelCase(field->name(), true));
+ 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(descriptor_->oneof_decl(i)->name()));
+ printer->Outdent();
+ printer->Print(
+ "}\n");
+ }
+
+ // Merge Optional and Required fields (after a _has_bit check).
+ int last_index = -1;
+
+ for (int i = 0; i < descriptor_->field_count(); ++i) {
+ const FieldDescriptor* field = descriptor_->field(i);
+
+ if (!field->is_repeated() && !field->containing_oneof()) {
+ // See above in GenerateClear for an explanation of this.
+ if (i / 8 != last_index / 8 || last_index < 0) {
+ if (last_index >= 0) {
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+ printer->Print(
+ "if (from._has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n",
+ "index", SimpleItoa(field->index()));
+ printer->Indent();
+ }
+
+ last_index = i;
+
+ printer->Print(
+ "if (from.has_$name$()) {\n",
+ "name", FieldName(field));
+ printer->Indent();
+
+ field_generators_.get(field).GenerateMergingCode(printer);
+
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+ }
+
+ if (last_index >= 0) {
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print("_extensions_.MergeFrom(from._extensions_);\n");
+ }
+
+ if (UseUnknownFieldSet(descriptor_->file())) {
+ printer->Print(
+ "mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n");
+ } else {
+ printer->Print(
+ "mutable_unknown_fields()->append(from.unknown_fields());\n");
+ }
+
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void MessageGenerator::
+GenerateCopyFrom(io::Printer* printer) {
+ if (HasDescriptorMethods(descriptor_->file())) {
+ // Generate the generalized CopyFrom (aka that which takes in the Message
+ // base class as a parameter).
+ printer->Print(
+ "void $classname$::CopyFrom(const ::google::protobuf::Message& from) {\n",
+ "classname", classname_);
+ printer->Indent();
+
+ printer->Print(
+ "if (&from == this) return;\n"
+ "Clear();\n"
+ "MergeFrom(from);\n");
+
+ printer->Outdent();
+ printer->Print("}\n\n");
+ }
+
+ // Generate the class-specific CopyFrom.
+ printer->Print(
+ "void $classname$::CopyFrom(const $classname$& from) {\n",
+ "classname", classname_);
+ printer->Indent();
+
+ printer->Print(
+ "if (&from == this) return;\n"
+ "Clear();\n"
+ "MergeFrom(from);\n");
+
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void MessageGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) {
+ if (descriptor_->options().message_set_wire_format()) {
+ // Special-case MessageSet.
+ printer->Print(
+ "bool $classname$::MergePartialFromCodedStream(\n"
+ " ::google::protobuf::io::CodedInputStream* input) {\n",
+ "classname", classname_);
+
+ PrintHandlingOptionalStaticInitializers(
+ descriptor_->file(), printer,
+ // With static initializers.
+ " return _extensions_.ParseMessageSet(input, default_instance_,\n"
+ " mutable_unknown_fields());\n",
+ // Without.
+ " return _extensions_.ParseMessageSet(input, &default_instance(),\n"
+ " mutable_unknown_fields());\n",
+ // Vars.
+ "classname", classname_);
+
+ printer->Print(
+ "}\n");
+ return;
+ }
+
+ printer->Print(
+ "bool $classname$::MergePartialFromCodedStream(\n"
+ " ::google::protobuf::io::CodedInputStream* input) {\n"
+ "#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure\n"
+ " ::google::protobuf::uint32 tag;\n",
+ "classname", classname_);
+
+ if (!UseUnknownFieldSet(descriptor_->file())) {
+ printer->Print(
+ " ::google::protobuf::io::StringOutputStream unknown_fields_string(\n"
+ " mutable_unknown_fields());\n"
+ " ::google::protobuf::io::CodedOutputStream unknown_fields_stream(\n"
+ " &unknown_fields_string);\n");
+ }
+
+ printer->Print(
+ " // @@protoc_insertion_point(parse_start:$full_name$)\n",
+ "full_name", descriptor_->full_name());
+
+ printer->Indent();
+ printer->Print("for (;;) {\n");
+ printer->Indent();
+
+ scoped_array<const FieldDescriptor*> ordered_fields(
+ SortFieldsByNumber(descriptor_));
+ uint32 maxtag = descriptor_->field_count() == 0 ? 0 :
+ WireFormat::MakeTag(ordered_fields[descriptor_->field_count() - 1]);
+ const int kCutoff0 = 127; // fits in 1-byte varint
+ const int kCutoff1 = (127 << 7) + 127; // fits in 2-byte varint
+ printer->Print("::std::pair< ::google::protobuf::uint32, bool> p = "
+ "input->ReadTagWithCutoff($max$);\n"
+ "tag = p.first;\n"
+ "if (!p.second) goto handle_unusual;\n",
+ "max", SimpleItoa(maxtag <= kCutoff0 ? kCutoff0 :
+ (maxtag <= kCutoff1 ? kCutoff1 :
+ maxtag)));
+ if (descriptor_->field_count() > 0) {
+ // We don't even want to print the switch() if we have no fields because
+ // MSVC dislikes switch() statements that contain only a default value.
+
+ // Note: If we just switched on the tag rather than the field number, we
+ // could avoid the need for the if() to check the wire type at the beginning
+ // of each case. However, this is actually a bit slower in practice as it
+ // creates a jump table that is 8x larger and sparser, and meanwhile the
+ // if()s are highly predictable.
+ printer->Print("switch (::google::protobuf::internal::WireFormatLite::"
+ "GetTagFieldNumber(tag)) {\n");
+
+ printer->Indent();
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = ordered_fields[i];
+
+ PrintFieldComment(printer, field);
+
+ printer->Print(
+ "case $number$: {\n",
+ "number", SimpleItoa(field->number()));
+ printer->Indent();
+ const FieldGenerator& field_generator = field_generators_.get(field);
+
+ // Emit code to parse the common, expected case.
+ printer->Print("if (tag == $commontag$) {\n",
+ "commontag", SimpleItoa(WireFormat::MakeTag(field)));
+
+ if (i > 0 || (field->is_repeated() && !field->options().packed())) {
+ printer->Print(
+ " parse_$name$:\n",
+ "name", field->name());
+ }
+
+ printer->Indent();
+ if (field->options().packed()) {
+ field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
+ } else {
+ field_generator.GenerateMergeFromCodedStream(printer);
+ }
+ printer->Outdent();
+
+ // Emit code to parse unexpectedly packed or unpacked values.
+ if (field->is_packable() && field->options().packed()) {
+ internal::WireFormatLite::WireType wiretype =
+ WireFormat::WireTypeForFieldType(field->type());
+ printer->Print("} else if (tag == $uncommontag$) {\n",
+ "uncommontag", SimpleItoa(
+ internal::WireFormatLite::MakeTag(
+ field->number(), wiretype)));
+ printer->Indent();
+ field_generator.GenerateMergeFromCodedStream(printer);
+ printer->Outdent();
+ } else if (field->is_packable() && !field->options().packed()) {
+ internal::WireFormatLite::WireType wiretype =
+ internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED;
+ printer->Print("} else if (tag == $uncommontag$) {\n",
+ "uncommontag", SimpleItoa(
+ internal::WireFormatLite::MakeTag(
+ field->number(), wiretype)));
+ printer->Indent();
+ field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
+ printer->Outdent();
+ }
+
+ printer->Print(
+ "} else {\n"
+ " goto handle_unusual;\n"
+ "}\n");
+
+ // 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.
+ 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?
+ printer->Print(
+ "if (input->ExpectAtEnd()) goto success;\n");
+ }
+
+ printer->Print(
+ "break;\n");
+
+ printer->Outdent();
+ printer->Print("}\n\n");
+ }
+
+ printer->Print("default: {\n");
+ printer->Indent();
+ }
+
+ printer->Outdent();
+ printer->Print("handle_unusual:\n");
+ printer->Indent();
+ // If tag is 0 or an end-group tag then this must be the end of the message.
+ printer->Print(
+ "if (tag == 0 ||\n"
+ " ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n"
+ " ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {\n"
+ " goto success;\n"
+ "}\n");
+
+ // Handle extension ranges.
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(
+ "if (");
+ for (int i = 0; i < descriptor_->extension_range_count(); i++) {
+ const Descriptor::ExtensionRange* range =
+ descriptor_->extension_range(i);
+ if (i > 0) printer->Print(" ||\n ");
+
+ uint32 start_tag = WireFormatLite::MakeTag(
+ range->start, static_cast<WireFormatLite::WireType>(0));
+ uint32 end_tag = WireFormatLite::MakeTag(
+ range->end, static_cast<WireFormatLite::WireType>(0));
+
+ if (range->end > FieldDescriptor::kMaxNumber) {
+ printer->Print(
+ "($start$u <= tag)",
+ "start", SimpleItoa(start_tag));
+ } else {
+ printer->Print(
+ "($start$u <= tag && tag < $end$u)",
+ "start", SimpleItoa(start_tag),
+ "end", SimpleItoa(end_tag));
+ }
+ }
+ printer->Print(") {\n");
+ if (UseUnknownFieldSet(descriptor_->file())) {
+ PrintHandlingOptionalStaticInitializers(
+ descriptor_->file(), printer,
+ // With static initializers.
+ " DO_(_extensions_.ParseField(tag, input, default_instance_,\n"
+ " mutable_unknown_fields()));\n",
+ // Without.
+ " DO_(_extensions_.ParseField(tag, input, &default_instance(),\n"
+ " mutable_unknown_fields()));\n");
+ } else {
+ PrintHandlingOptionalStaticInitializers(
+ descriptor_->file(), printer,
+ // With static initializers.
+ " DO_(_extensions_.ParseField(tag, input, default_instance_,\n"
+ " &unknown_fields_stream));\n",
+ // Without.
+ " DO_(_extensions_.ParseField(tag, input, &default_instance(),\n"
+ " &unknown_fields_stream));\n");
+ }
+ printer->Print(
+ " continue;\n"
+ "}\n");
+ }
+
+ // We really don't recognize this tag. Skip it.
+ if (UseUnknownFieldSet(descriptor_->file())) {
+ printer->Print(
+ "DO_(::google::protobuf::internal::WireFormat::SkipField(\n"
+ " input, tag, mutable_unknown_fields()));\n");
+ } else {
+ printer->Print(
+ "DO_(::google::protobuf::internal::WireFormatLite::SkipField(\n"
+ " input, tag, &unknown_fields_stream));\n");
+ }
+
+ if (descriptor_->field_count() > 0) {
+ printer->Print("break;\n");
+ printer->Outdent();
+ printer->Print("}\n"); // default:
+ printer->Outdent();
+ printer->Print("}\n"); // switch
+ }
+
+ printer->Outdent();
+ printer->Outdent();
+ printer->Print(
+ " }\n" // for (;;)
+ "success:\n"
+ " // @@protoc_insertion_point(parse_success:$full_name$)\n"
+ " return true;\n"
+ "failure:\n"
+ " // @@protoc_insertion_point(parse_failure:$full_name$)\n"
+ " return false;\n"
+ "#undef DO_\n"
+ "}\n", "full_name", descriptor_->full_name());
+}
+
+void MessageGenerator::GenerateSerializeOneField(
+ io::Printer* printer, const FieldDescriptor* field, bool to_array) {
+ PrintFieldComment(printer, field);
+
+ if (!field->is_repeated()) {
+ printer->Print(
+ "if (has_$name$()) {\n",
+ "name", FieldName(field));
+ printer->Indent();
+ }
+
+ if (to_array) {
+ field_generators_.get(field).GenerateSerializeWithCachedSizesToArray(
+ printer);
+ } else {
+ field_generators_.get(field).GenerateSerializeWithCachedSizes(printer);
+ }
+
+ if (!field->is_repeated()) {
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+ printer->Print("\n");
+}
+
+void MessageGenerator::GenerateSerializeOneExtensionRange(
+ io::Printer* printer, const Descriptor::ExtensionRange* range,
+ bool to_array) {
+ map<string, string> vars;
+ vars["start"] = SimpleItoa(range->start);
+ vars["end"] = SimpleItoa(range->end);
+ printer->Print(vars,
+ "// Extension range [$start$, $end$)\n");
+ if (to_array) {
+ printer->Print(vars,
+ "target = _extensions_.SerializeWithCachedSizesToArray(\n"
+ " $start$, $end$, target);\n\n");
+ } else {
+ printer->Print(vars,
+ "_extensions_.SerializeWithCachedSizes(\n"
+ " $start$, $end$, output);\n\n");
+ }
+}
+
+void MessageGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) {
+ if (descriptor_->options().message_set_wire_format()) {
+ // Special-case MessageSet.
+ printer->Print(
+ "void $classname$::SerializeWithCachedSizes(\n"
+ " ::google::protobuf::io::CodedOutputStream* output) const {\n"
+ " _extensions_.SerializeMessageSetWithCachedSizes(output);\n",
+ "classname", classname_);
+ GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file()));
+ printer->Print(
+ " ::google::protobuf::internal::WireFormat::SerializeUnknownMessageSetItems(\n"
+ " unknown_fields(), output);\n");
+ printer->Print(
+ "}\n");
+ return;
+ }
+
+ printer->Print(
+ "void $classname$::SerializeWithCachedSizes(\n"
+ " ::google::protobuf::io::CodedOutputStream* output) const {\n",
+ "classname", classname_);
+ printer->Indent();
+
+ printer->Print(
+ "// @@protoc_insertion_point(serialize_start:$full_name$)\n",
+ "full_name", descriptor_->full_name());
+
+ GenerateSerializeWithCachedSizesBody(printer, false);
+
+ printer->Print(
+ "// @@protoc_insertion_point(serialize_end:$full_name$)\n",
+ "full_name", descriptor_->full_name());
+
+ printer->Outdent();
+ printer->Print(
+ "}\n");
+}
+
+void MessageGenerator::
+GenerateSerializeWithCachedSizesToArray(io::Printer* printer) {
+ if (descriptor_->options().message_set_wire_format()) {
+ // Special-case MessageSet.
+ printer->Print(
+ "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n"
+ " ::google::protobuf::uint8* target) const {\n"
+ " target =\n"
+ " _extensions_.SerializeMessageSetWithCachedSizesToArray(target);\n",
+ "classname", classname_);
+ GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file()));
+ printer->Print(
+ " target = ::google::protobuf::internal::WireFormat::\n"
+ " SerializeUnknownMessageSetItemsToArray(\n"
+ " unknown_fields(), target);\n");
+ printer->Print(
+ " return target;\n"
+ "}\n");
+ return;
+ }
+
+ printer->Print(
+ "::google::protobuf::uint8* $classname$::SerializeWithCachedSizesToArray(\n"
+ " ::google::protobuf::uint8* target) const {\n",
+ "classname", classname_);
+ printer->Indent();
+
+ printer->Print(
+ "// @@protoc_insertion_point(serialize_to_array_start:$full_name$)\n",
+ "full_name", descriptor_->full_name());
+
+ GenerateSerializeWithCachedSizesBody(printer, true);
+
+ printer->Print(
+ "// @@protoc_insertion_point(serialize_to_array_end:$full_name$)\n",
+ "full_name", descriptor_->full_name());
+
+ printer->Outdent();
+ printer->Print(
+ " return target;\n"
+ "}\n");
+}
+
+void MessageGenerator::
+GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) {
+ scoped_array<const FieldDescriptor*> ordered_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));
+ }
+ sort(sorted_extensions.begin(), sorted_extensions.end(),
+ ExtensionRangeSorter());
+
+ // Merge the fields and the extension ranges, both sorted by field number.
+ int i, j;
+ for (i = 0, j = 0;
+ i < descriptor_->field_count() || j < sorted_extensions.size();
+ ) {
+ if (i == descriptor_->field_count()) {
+ GenerateSerializeOneExtensionRange(printer,
+ sorted_extensions[j++],
+ to_array);
+ } else if (j == sorted_extensions.size()) {
+ GenerateSerializeOneField(printer, ordered_fields[i++], to_array);
+ } else if (ordered_fields[i]->number() < sorted_extensions[j]->start) {
+ GenerateSerializeOneField(printer, ordered_fields[i++], to_array);
+ } else {
+ GenerateSerializeOneExtensionRange(printer,
+ sorted_extensions[j++],
+ to_array);
+ }
+ }
+
+ if (UseUnknownFieldSet(descriptor_->file())) {
+ printer->Print("if (!unknown_fields().empty()) {\n");
+ printer->Indent();
+ if (to_array) {
+ printer->Print(
+ "target = "
+ "::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n"
+ " unknown_fields(), target);\n");
+ } else {
+ printer->Print(
+ "::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n"
+ " unknown_fields(), output);\n");
+ }
+ printer->Outdent();
+
+ printer->Print(
+ "}\n");
+ } else {
+ printer->Print(
+ "output->WriteRaw(unknown_fields().data(),\n"
+ " unknown_fields().size());\n");
+ }
+}
+
+void MessageGenerator::
+GenerateByteSize(io::Printer* printer) {
+ if (descriptor_->options().message_set_wire_format()) {
+ // Special-case MessageSet.
+ printer->Print(
+ "int $classname$::ByteSize() const {\n"
+ " int total_size = _extensions_.MessageSetByteSize();\n",
+ "classname", classname_);
+ GOOGLE_CHECK(UseUnknownFieldSet(descriptor_->file()));
+ printer->Print(
+ " total_size += ::google::protobuf::internal::WireFormat::\n"
+ " ComputeUnknownMessageSetItemsSize(unknown_fields());\n");
+ printer->Print(
+ " GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
+ " _cached_size_ = total_size;\n"
+ " GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
+ " return total_size;\n"
+ "}\n");
+ return;
+ }
+
+ printer->Print(
+ "int $classname$::ByteSize() const {\n",
+ "classname", classname_);
+ printer->Indent();
+ printer->Print(
+ "int total_size = 0;\n"
+ "\n");
+
+ int last_index = -1;
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+
+ if (!field->is_repeated() && !field->containing_oneof()) {
+ // See above in GenerateClear for an explanation of this.
+ // TODO(kenton): Share code? Unclear how to do so without
+ // over-engineering.
+ if ((i / 8) != (last_index / 8) ||
+ last_index < 0) {
+ if (last_index >= 0) {
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+ printer->Print(
+ "if (_has_bits_[$index$ / 32] & (0xffu << ($index$ % 32))) {\n",
+ "index", SimpleItoa(field->index()));
+ printer->Indent();
+ }
+ last_index = i;
+
+ PrintFieldComment(printer, field);
+
+ printer->Print(
+ "if (has_$name$()) {\n",
+ "name", FieldName(field));
+ printer->Indent();
+
+ field_generators_.get(field).GenerateByteSize(printer);
+
+ printer->Outdent();
+ printer->Print(
+ "}\n"
+ "\n");
+ }
+ }
+
+ if (last_index >= 0) {
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+
+ // Repeated fields don't use _has_bits_ so we count them in a separate
+ // pass.
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+
+ if (field->is_repeated()) {
+ PrintFieldComment(printer, field);
+ field_generators_.get(field).GenerateByteSize(printer);
+ printer->Print("\n");
+ }
+ }
+
+ // Fields inside a oneof don't use _has_bits_ so we count them in a separate
+ // pass.
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ printer->Print(
+ "switch ($oneofname$_case()) {\n",
+ "oneofname", descriptor_->oneof_decl(i)->name());
+ printer->Indent();
+ for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
+ const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
+ PrintFieldComment(printer, field);
+ printer->Print(
+ "case k$field_name$: {\n",
+ "field_name", UnderscoresToCamelCase(field->name(), true));
+ printer->Indent();
+ field_generators_.get(field).GenerateByteSize(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(descriptor_->oneof_decl(i)->name()));
+ printer->Outdent();
+ printer->Print(
+ "}\n");
+ }
+
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(
+ "total_size += _extensions_.ByteSize();\n"
+ "\n");
+ }
+
+ if (UseUnknownFieldSet(descriptor_->file())) {
+ printer->Print("if (!unknown_fields().empty()) {\n");
+ printer->Indent();
+ printer->Print(
+ "total_size +=\n"
+ " ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n"
+ " unknown_fields());\n");
+ printer->Outdent();
+ printer->Print("}\n");
+ } else {
+ printer->Print(
+ "total_size += unknown_fields().size();\n"
+ "\n");
+ }
+
+ // We update _cached_size_ even though this is a const method. In theory,
+ // this is not thread-compatible, because concurrent writes have undefined
+ // results. In practice, since any concurrent writes will be writing the
+ // exact same value, it works on all common processors. In a future version
+ // of C++, _cached_size_ should be made into an atomic<int>.
+ printer->Print(
+ "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
+ "_cached_size_ = total_size;\n"
+ "GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
+ "return total_size;\n");
+
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+void MessageGenerator::
+GenerateIsInitialized(io::Printer* printer) {
+ printer->Print(
+ "bool $classname$::IsInitialized() const {\n",
+ "classname", classname_);
+ printer->Indent();
+
+ // Check that all required fields in this message are set. We can do this
+ // most efficiently by checking 32 "has bits" at a time.
+ int has_bits_array_size = (descriptor_->field_count() + 31) / 32;
+ for (int i = 0; i < has_bits_array_size; i++) {
+ uint32 mask = 0;
+ for (int bit = 0; bit < 32; bit++) {
+ int index = i * 32 + bit;
+ if (index >= descriptor_->field_count()) break;
+ const FieldDescriptor* field = descriptor_->field(index);
+
+ if (field->is_required()) {
+ mask |= 1 << bit;
+ }
+ }
+
+ 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));
+ }
+ }
+
+ // Now check that all embedded messages are initialized.
+ printer->Print("\n");
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
+ !ShouldIgnoreRequiredFieldCheck(field) &&
+ HasRequiredFields(field->message_type())) {
+ if (field->is_repeated()) {
+ printer->Print(
+ "if (!::google::protobuf::internal::AllAreInitialized(this->$name$()))"
+ " return false;\n",
+ "name", FieldName(field));
+ } else {
+ if (field->options().weak()) {
+ // For weak fields, use the data member (google::protobuf::Message*) instead
+ // of the getter to avoid a link dependency on the weak message type
+ // which is only forward declared.
+ printer->Print(
+ "if (has_$name$()) {\n"
+ " if (!this->$name$_->IsInitialized()) return false;\n"
+ "}\n",
+ "name", FieldName(field));
+ } else {
+ printer->Print(
+ "if (has_$name$()) {\n"
+ " if (!this->$name$().IsInitialized()) return false;\n"
+ "}\n",
+ "name", FieldName(field));
+ }
+ }
+ }
+ }
+
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(
+ "\n"
+ "if (!_extensions_.IsInitialized()) return false;");
+ }
+
+ printer->Outdent();
+ printer->Print(
+ " return true;\n"
+ "}\n");
+}
+
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_message.h b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_message.h
new file mode 100644
index 00000000000..aaebe1e0994
--- /dev/null
+++ b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_message.h
@@ -0,0 +1,175 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__
+
+#include <memory>
+#include <string>
+#include <vector>
+#include "google/protobuf/compiler/cpp/cpp_field.h"
+#include "google/protobuf/compiler/cpp/cpp_options.h"
+
+namespace google {
+namespace protobuf {
+ namespace io {
+ class Printer; // printer.h
+ }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class EnumGenerator; // enum.h
+class ExtensionGenerator; // extension.h
+
+class MessageGenerator {
+ public:
+ // See generator.cc for the meaning of dllexport_decl.
+ explicit MessageGenerator(const Descriptor* descriptor,
+ const Options& options);
+ ~MessageGenerator();
+
+ // Header stuff.
+
+ // Generate foward declarations for this class and all its nested types.
+ void GenerateForwardDeclaration(io::Printer* printer);
+
+ // Generate definitions of all nested enums (must come before class
+ // definitions because those classes use the enums definitions).
+ void GenerateEnumDefinitions(io::Printer* printer);
+
+ // Generate specializations of GetEnumDescriptor<MyEnum>().
+ // Precondition: in ::google::protobuf namespace.
+ void GenerateGetEnumDescriptorSpecializations(io::Printer* printer);
+
+ // Generate definitions for this class and all its nested types.
+ void GenerateClassDefinition(io::Printer* printer);
+
+ // Generate definitions of inline methods (placed at the end of the header
+ // file).
+ void GenerateInlineMethods(io::Printer* printer);
+
+ // Source file stuff.
+
+ // Generate code which declares all the global descriptor pointers which
+ // will be initialized by the methods below.
+ void GenerateDescriptorDeclarations(io::Printer* printer);
+
+ // Generate code that initializes the global variable storing the message's
+ // descriptor.
+ void GenerateDescriptorInitializer(io::Printer* printer, int index);
+
+ // Generate code that calls MessageFactory::InternalRegisterGeneratedMessage()
+ // for all types.
+ void GenerateTypeRegistrations(io::Printer* printer);
+
+ // Generates code that allocates the message's default instance.
+ void GenerateDefaultInstanceAllocator(io::Printer* printer);
+
+ // Generates code that initializes the message's default instance. This
+ // is separate from allocating because all default instances must be
+ // allocated before any can be initialized.
+ void GenerateDefaultInstanceInitializer(io::Printer* printer);
+
+ // Generates code that should be run when ShutdownProtobufLibrary() is called,
+ // to delete all dynamically-allocated objects.
+ void GenerateShutdownCode(io::Printer* printer);
+
+ // Generate all non-inline methods for this class.
+ void GenerateClassMethods(io::Printer* printer);
+
+ private:
+ // Generate declarations and definitions of accessors for fields.
+ void GenerateFieldAccessorDeclarations(io::Printer* printer);
+ void GenerateFieldAccessorDefinitions(io::Printer* printer);
+
+ // Generate the field offsets array.
+ void GenerateOffsets(io::Printer* printer);
+
+ // Generate constructors and destructor.
+ void GenerateStructors(io::Printer* printer);
+
+ // The compiler typically generates multiple copies of each constructor and
+ // destructor: http://gcc.gnu.org/bugs.html#nonbugs_cxx
+ // Placing common code in a separate method reduces the generated code size.
+ //
+ // Generate the shared constructor code.
+ void GenerateSharedConstructorCode(io::Printer* printer);
+ // Generate the shared destructor code.
+ void GenerateSharedDestructorCode(io::Printer* printer);
+
+ // Generate standard Message methods.
+ void GenerateClear(io::Printer* printer);
+ void GenerateOneofClear(io::Printer* printer);
+ void GenerateMergeFromCodedStream(io::Printer* printer);
+ void GenerateSerializeWithCachedSizes(io::Printer* printer);
+ void GenerateSerializeWithCachedSizesToArray(io::Printer* printer);
+ void GenerateSerializeWithCachedSizesBody(io::Printer* printer,
+ bool to_array);
+ void GenerateByteSize(io::Printer* printer);
+ void GenerateMergeFrom(io::Printer* printer);
+ void GenerateCopyFrom(io::Printer* printer);
+ void GenerateSwap(io::Printer* printer);
+ void GenerateIsInitialized(io::Printer* printer);
+
+ // Helpers for GenerateSerializeWithCachedSizes().
+ void GenerateSerializeOneField(io::Printer* printer,
+ const FieldDescriptor* field,
+ bool unbounded);
+ void GenerateSerializeOneExtensionRange(
+ io::Printer* printer, const Descriptor::ExtensionRange* range,
+ bool unbounded);
+
+
+ const Descriptor* descriptor_;
+ string classname_;
+ Options options_;
+ FieldGeneratorMap field_generators_;
+ vector< vector<string> > runs_of_fields_; // that might be trivially cleared
+ scoped_array<scoped_ptr<MessageGenerator> > nested_generators_;
+ scoped_array<scoped_ptr<EnumGenerator> > enum_generators_;
+ scoped_array<scoped_ptr<ExtensionGenerator> > extension_generators_;
+ bool uses_string_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator);
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__
diff --git a/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_message_field.cc b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_message_field.cc
new file mode 100644
index 00000000000..789a7750ab4
--- /dev/null
+++ b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_message_field.cc
@@ -0,0 +1,375 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include "google/protobuf/compiler/cpp/cpp_message_field.h"
+#include "google/protobuf/compiler/cpp/cpp_helpers.h"
+#include <google/protobuf/io/printer.h>
+#include "google/protobuf/stubs/strutil.h"
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+namespace {
+
+void SetMessageVariables(const FieldDescriptor* descriptor,
+ map<string, string>* variables,
+ const Options& options) {
+ SetCommonFieldVariables(descriptor, variables, options);
+ (*variables)["type"] = FieldMessageTypeName(descriptor);
+ (*variables)["stream_writer"] = (*variables)["declared_type"] +
+ (HasFastArraySerialization(descriptor->message_type()->file()) ?
+ "MaybeToArray" :
+ "");
+ // NOTE: Escaped here to unblock proto1->proto2 migration.
+ // TODO(liujisi): Extend this to apply for other conflicting methods.
+ (*variables)["release_name"] =
+ SafeFunctionName(descriptor->containing_type(),
+ descriptor, "release_");
+ (*variables)["full_name"] = descriptor->full_name();
+}
+
+} // namespace
+
+// ===================================================================
+
+MessageFieldGenerator::
+MessageFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : descriptor_(descriptor) {
+ SetMessageVariables(descriptor, &variables_, options);
+}
+
+MessageFieldGenerator::~MessageFieldGenerator() {}
+
+void MessageFieldGenerator::
+GeneratePrivateMembers(io::Printer* printer) const {
+ printer->Print(variables_, "$type$* $name$_;\n");
+}
+
+void MessageFieldGenerator::
+GenerateAccessorDeclarations(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline const $type$& $name$() const$deprecation$;\n"
+ "inline $type$* mutable_$name$()$deprecation$;\n"
+ "inline $type$* $release_name$()$deprecation$;\n"
+ "inline void set_allocated_$name$($type$* $name$)$deprecation$;\n");
+}
+
+void MessageFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline const $type$& $classname$::$name$() const {\n"
+ " // @@protoc_insertion_point(field_get:$full_name$)\n");
+
+ PrintHandlingOptionalStaticInitializers(
+ variables_, descriptor_->file(), printer,
+ // With static initializers.
+ " return $name$_ != NULL ? *$name$_ : *default_instance_->$name$_;\n",
+ // Without.
+ " return $name$_ != NULL ? *$name$_ : *default_instance().$name$_;\n");
+
+ printer->Print(variables_,
+ "}\n"
+ "inline $type$* $classname$::mutable_$name$() {\n"
+ " set_has_$name$();\n"
+ " if ($name$_ == NULL) $name$_ = new $type$;\n"
+ " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
+ " return $name$_;\n"
+ "}\n"
+ "inline $type$* $classname$::$release_name$() {\n"
+ " clear_has_$name$();\n"
+ " $type$* temp = $name$_;\n"
+ " $name$_ = NULL;\n"
+ " return temp;\n"
+ "}\n"
+ "inline void $classname$::set_allocated_$name$($type$* $name$) {\n"
+ " delete $name$_;\n"
+ " $name$_ = $name$;\n"
+ " if ($name$) {\n"
+ " set_has_$name$();\n"
+ " } else {\n"
+ " clear_has_$name$();\n"
+ " }\n"
+ " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
+ "}\n");
+}
+
+void MessageFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($name$_ != NULL) $name$_->$type$::Clear();\n");
+}
+
+void MessageFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "mutable_$name$()->$type$::MergeFrom(from.$name$());\n");
+}
+
+void MessageFieldGenerator::
+GenerateSwappingCode(io::Printer* printer) const {
+ printer->Print(variables_, "std::swap($name$_, other->$name$_);\n");
+}
+
+void MessageFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_ = NULL;\n");
+}
+
+void MessageFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+ if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) {
+ printer->Print(variables_,
+ "DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n"
+ " input, mutable_$name$()));\n");
+ } else {
+ printer->Print(variables_,
+ "DO_(::google::protobuf::internal::WireFormatLite::ReadGroupNoVirtual(\n"
+ " $number$, input, mutable_$name$()));\n");
+ }
+}
+
+void MessageFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+ printer->Print(variables_,
+ "::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n"
+ " $number$, this->$name$(), output);\n");
+}
+
+void MessageFieldGenerator::
+GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
+ printer->Print(variables_,
+ "target = ::google::protobuf::internal::WireFormatLite::\n"
+ " Write$declared_type$NoVirtualToArray(\n"
+ " $number$, this->$name$(), target);\n");
+}
+
+void MessageFieldGenerator::
+GenerateByteSize(io::Printer* printer) const {
+ printer->Print(variables_,
+ "total_size += $tag_size$ +\n"
+ " ::google::protobuf::internal::WireFormatLite::$declared_type$SizeNoVirtual(\n"
+ " this->$name$());\n");
+}
+
+// ===================================================================
+
+MessageOneofFieldGenerator::
+MessageOneofFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : MessageFieldGenerator(descriptor, options) {
+ SetCommonOneofFieldVariables(descriptor, &variables_);
+}
+
+MessageOneofFieldGenerator::~MessageOneofFieldGenerator() {}
+
+void MessageOneofFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline const $type$& $classname$::$name$() const {\n"
+ " return has_$name$() ? *$oneof_prefix$$name$_\n"
+ " : $type$::default_instance();\n"
+ "}\n"
+ "inline $type$* $classname$::mutable_$name$() {\n"
+ " if (!has_$name$()) {\n"
+ " clear_$oneof_name$();\n"
+ " set_has_$name$();\n"
+ " $oneof_prefix$$name$_ = new $type$;\n"
+ " }\n"
+ " return $oneof_prefix$$name$_;\n"
+ "}\n"
+ "inline $type$* $classname$::$release_name$() {\n"
+ " if (has_$name$()) {\n"
+ " clear_has_$oneof_name$();\n"
+ " $type$* temp = $oneof_prefix$$name$_;\n"
+ " $oneof_prefix$$name$_ = NULL;\n"
+ " return temp;\n"
+ " } else {\n"
+ " return NULL;\n"
+ " }\n"
+ "}\n"
+ "inline void $classname$::set_allocated_$name$($type$* $name$) {\n"
+ " clear_$oneof_name$();\n"
+ " if ($name$) {\n"
+ " set_has_$name$();\n"
+ " $oneof_prefix$$name$_ = $name$;\n"
+ " }\n"
+ "}\n");
+}
+
+void MessageOneofFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+ // if it is the active field, it cannot be NULL.
+ printer->Print(variables_,
+ "delete $oneof_prefix$$name$_;\n");
+}
+
+void MessageOneofFieldGenerator::
+GenerateSwappingCode(io::Printer* printer) const {
+ // Don't print any swapping code. Swapping the union will swap this field.
+}
+
+void MessageOneofFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+ // Don't print any constructor code. The field is in a union. We allocate
+ // space only when this field is used.
+}
+
+// ===================================================================
+
+RepeatedMessageFieldGenerator::
+RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : descriptor_(descriptor) {
+ SetMessageVariables(descriptor, &variables_, options);
+}
+
+RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
+
+void RepeatedMessageFieldGenerator::
+GeneratePrivateMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "::google::protobuf::RepeatedPtrField< $type$ > $name$_;\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateAccessorDeclarations(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline const $type$& $name$(int index) const$deprecation$;\n"
+ "inline $type$* mutable_$name$(int index)$deprecation$;\n"
+ "inline $type$* add_$name$()$deprecation$;\n");
+ printer->Print(variables_,
+ "inline const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
+ " $name$() const$deprecation$;\n"
+ "inline ::google::protobuf::RepeatedPtrField< $type$ >*\n"
+ " mutable_$name$()$deprecation$;\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline const $type$& $classname$::$name$(int index) const {\n"
+ " // @@protoc_insertion_point(field_get:$full_name$)\n"
+ " return $name$_.$cppget$(index);\n"
+ "}\n"
+ "inline $type$* $classname$::mutable_$name$(int index) {\n"
+ " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
+ " return $name$_.Mutable(index);\n"
+ "}\n"
+ "inline $type$* $classname$::add_$name$() {\n"
+ " // @@protoc_insertion_point(field_add:$full_name$)\n"
+ " return $name$_.Add();\n"
+ "}\n");
+ printer->Print(variables_,
+ "inline const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
+ "$classname$::$name$() const {\n"
+ " // @@protoc_insertion_point(field_list:$full_name$)\n"
+ " return $name$_;\n"
+ "}\n"
+ "inline ::google::protobuf::RepeatedPtrField< $type$ >*\n"
+ "$classname$::mutable_$name$() {\n"
+ " // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
+ " return &$name$_;\n"
+ "}\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_.Clear();\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateSwappingCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_.Swap(&other->$name$_);\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+ // Not needed for repeated fields.
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+ if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) {
+ printer->Print(variables_,
+ "DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n"
+ " input, add_$name$()));\n");
+ } else {
+ printer->Print(variables_,
+ "DO_(::google::protobuf::internal::WireFormatLite::ReadGroupNoVirtual(\n"
+ " $number$, input, add_$name$()));\n");
+ }
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+ printer->Print(variables_,
+ "for (int i = 0; i < this->$name$_size(); i++) {\n"
+ " ::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n"
+ " $number$, this->$name$(i), output);\n"
+ "}\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
+ printer->Print(variables_,
+ "for (int i = 0; i < this->$name$_size(); i++) {\n"
+ " target = ::google::protobuf::internal::WireFormatLite::\n"
+ " Write$declared_type$NoVirtualToArray(\n"
+ " $number$, this->$name$(i), target);\n"
+ "}\n");
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateByteSize(io::Printer* printer) const {
+ printer->Print(variables_,
+ "total_size += $tag_size$ * this->$name$_size();\n"
+ "for (int i = 0; i < this->$name$_size(); i++) {\n"
+ " total_size +=\n"
+ " ::google::protobuf::internal::WireFormatLite::$declared_type$SizeNoVirtual(\n"
+ " this->$name$(i));\n"
+ "}\n");
+}
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_message_field.h b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_message_field.h
new file mode 100644
index 00000000000..1dd03907c60
--- /dev/null
+++ b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_message_field.h
@@ -0,0 +1,121 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_FIELD_H__
+
+#include <map>
+#include <string>
+#include "google/protobuf/compiler/cpp/cpp_field.h"
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class MessageFieldGenerator : public FieldGenerator {
+ public:
+ explicit MessageFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ ~MessageFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ void GeneratePrivateMembers(io::Printer* printer) const;
+ void GenerateAccessorDeclarations(io::Printer* printer) const;
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+ void GenerateClearingCode(io::Printer* printer) const;
+ void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateSwappingCode(io::Printer* printer) const;
+ void GenerateConstructorCode(io::Printer* printer) const;
+ void GenerateMergeFromCodedStream(io::Printer* printer) const;
+ void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
+ void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
+ void GenerateByteSize(io::Printer* printer) const;
+
+ protected:
+ const FieldDescriptor* descriptor_;
+ map<string, string> variables_;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator);
+};
+
+class MessageOneofFieldGenerator : public MessageFieldGenerator {
+ public:
+ explicit MessageOneofFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ ~MessageOneofFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+ void GenerateClearingCode(io::Printer* printer) const;
+ void GenerateSwappingCode(io::Printer* printer) const;
+ void GenerateConstructorCode(io::Printer* printer) const;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageOneofFieldGenerator);
+};
+
+class RepeatedMessageFieldGenerator : public FieldGenerator {
+ public:
+ explicit RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ ~RepeatedMessageFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ void GeneratePrivateMembers(io::Printer* printer) const;
+ void GenerateAccessorDeclarations(io::Printer* printer) const;
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+ void GenerateClearingCode(io::Printer* printer) const;
+ void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateSwappingCode(io::Printer* printer) const;
+ void GenerateConstructorCode(io::Printer* printer) const;
+ void GenerateMergeFromCodedStream(io::Printer* printer) const;
+ void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
+ void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
+ void GenerateByteSize(io::Printer* printer) const;
+
+ private:
+ const FieldDescriptor* descriptor_;
+ map<string, string> variables_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator);
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_FIELD_H__
diff --git a/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_options.h b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_options.h
new file mode 100644
index 00000000000..0c99cff1878
--- /dev/null
+++ b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_options.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.
+
+// Author: rennie@google.com (Jeffrey Rennie)
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_OPTIONS_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_OPTIONS_H__
+
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+// Generator options:
+struct Options {
+ Options() : safe_boundary_check(false) {
+ }
+ string dllexport_decl;
+ bool safe_boundary_check;
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_OPTIONS_H__
diff --git a/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_primitive_field.cc b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_primitive_field.cc
new file mode 100644
index 00000000000..f9f13cee742
--- /dev/null
+++ b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_primitive_field.cc
@@ -0,0 +1,451 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include "google/protobuf/compiler/cpp/cpp_primitive_field.h"
+#include "google/protobuf/compiler/cpp/cpp_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 cpp {
+
+using internal::WireFormatLite;
+
+namespace {
+
+// For encodings with fixed sizes, returns that size in bytes. Otherwise
+// returns -1.
+int FixedSize(FieldDescriptor::Type type) {
+ switch (type) {
+ case FieldDescriptor::TYPE_INT32 : return -1;
+ case FieldDescriptor::TYPE_INT64 : return -1;
+ case FieldDescriptor::TYPE_UINT32 : return -1;
+ case FieldDescriptor::TYPE_UINT64 : return -1;
+ case FieldDescriptor::TYPE_SINT32 : return -1;
+ case FieldDescriptor::TYPE_SINT64 : return -1;
+ case FieldDescriptor::TYPE_FIXED32 : return WireFormatLite::kFixed32Size;
+ case FieldDescriptor::TYPE_FIXED64 : return WireFormatLite::kFixed64Size;
+ case FieldDescriptor::TYPE_SFIXED32: return WireFormatLite::kSFixed32Size;
+ case FieldDescriptor::TYPE_SFIXED64: return WireFormatLite::kSFixed64Size;
+ case FieldDescriptor::TYPE_FLOAT : return WireFormatLite::kFloatSize;
+ case FieldDescriptor::TYPE_DOUBLE : return WireFormatLite::kDoubleSize;
+
+ case FieldDescriptor::TYPE_BOOL : return WireFormatLite::kBoolSize;
+ case FieldDescriptor::TYPE_ENUM : return -1;
+
+ case FieldDescriptor::TYPE_STRING : return -1;
+ case FieldDescriptor::TYPE_BYTES : return -1;
+ case FieldDescriptor::TYPE_GROUP : return -1;
+ case FieldDescriptor::TYPE_MESSAGE : return -1;
+
+ // No default because we want the compiler to complain if any new
+ // types are added.
+ }
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return -1;
+}
+
+void SetPrimitiveVariables(const FieldDescriptor* descriptor,
+ map<string, string>* variables,
+ const Options& options) {
+ SetCommonFieldVariables(descriptor, variables, options);
+ (*variables)["type"] = PrimitiveTypeName(descriptor->cpp_type());
+ (*variables)["default"] = DefaultValue(descriptor);
+ (*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor));
+ int fixed_size = FixedSize(descriptor->type());
+ if (fixed_size != -1) {
+ (*variables)["fixed_size"] = SimpleItoa(fixed_size);
+ }
+ (*variables)["wire_format_field_type"] =
+ "::google::protobuf::internal::WireFormatLite::" + FieldDescriptorProto_Type_Name(
+ static_cast<FieldDescriptorProto_Type>(descriptor->type()));
+ (*variables)["full_name"] = descriptor->full_name();
+}
+
+} // namespace
+
+// ===================================================================
+
+PrimitiveFieldGenerator::
+PrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : descriptor_(descriptor) {
+ SetPrimitiveVariables(descriptor, &variables_, options);
+}
+
+PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {}
+
+void PrimitiveFieldGenerator::
+GeneratePrivateMembers(io::Printer* printer) const {
+ printer->Print(variables_, "$type$ $name$_;\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateAccessorDeclarations(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline $type$ $name$() const$deprecation$;\n"
+ "inline void set_$name$($type$ value)$deprecation$;\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline $type$ $classname$::$name$() const {\n"
+ " // @@protoc_insertion_point(field_get:$full_name$)\n"
+ " return $name$_;\n"
+ "}\n"
+ "inline void $classname$::set_$name$($type$ value) {\n"
+ " set_has_$name$();\n"
+ " $name$_ = value;\n"
+ " // @@protoc_insertion_point(field_set:$full_name$)\n"
+ "}\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_ = $default$;\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+ printer->Print(variables_, "set_$name$(from.$name$());\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateSwappingCode(io::Printer* printer) const {
+ printer->Print(variables_, "std::swap($name$_, other->$name$_);\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_ = $default$;\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+ printer->Print(variables_,
+ "DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n"
+ " $type$, $wire_format_field_type$>(\n"
+ " input, &$name$_)));\n"
+ "set_has_$name$();\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+ printer->Print(variables_,
+ "::google::protobuf::internal::WireFormatLite::Write$declared_type$("
+ "$number$, this->$name$(), output);\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
+ printer->Print(variables_,
+ "target = ::google::protobuf::internal::WireFormatLite::Write$declared_type$ToArray("
+ "$number$, this->$name$(), target);\n");
+}
+
+void PrimitiveFieldGenerator::
+GenerateByteSize(io::Printer* printer) const {
+ int fixed_size = FixedSize(descriptor_->type());
+ if (fixed_size == -1) {
+ printer->Print(variables_,
+ "total_size += $tag_size$ +\n"
+ " ::google::protobuf::internal::WireFormatLite::$declared_type$Size(\n"
+ " this->$name$());\n");
+ } else {
+ printer->Print(variables_,
+ "total_size += $tag_size$ + $fixed_size$;\n");
+ }
+}
+
+// ===================================================================
+
+PrimitiveOneofFieldGenerator::
+PrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : PrimitiveFieldGenerator(descriptor, options) {
+ SetCommonOneofFieldVariables(descriptor, &variables_);
+}
+
+PrimitiveOneofFieldGenerator::~PrimitiveOneofFieldGenerator() {}
+
+void PrimitiveOneofFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline $type$ $classname$::$name$() const {\n"
+ " if (has_$name$()) {\n"
+ " return $oneof_prefix$$name$_;\n"
+ " }\n"
+ " return $default$;\n"
+ "}\n"
+ "inline void $classname$::set_$name$($type$ value) {\n"
+ " if (!has_$name$()) {\n"
+ " clear_$oneof_name$();\n"
+ " set_has_$name$();\n"
+ " }\n"
+ " $oneof_prefix$$name$_ = value;\n"
+ "}\n");
+}
+
+void PrimitiveOneofFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+ printer->Print(variables_, "$oneof_prefix$$name$_ = $default$;\n");
+}
+
+void PrimitiveOneofFieldGenerator::
+GenerateSwappingCode(io::Printer* printer) const {
+ // Don't print any swapping code. Swapping the union will swap this field.
+}
+
+void PrimitiveOneofFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ " $classname$_default_oneof_instance_->$name$_ = $default$;\n");
+}
+
+void PrimitiveOneofFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+ printer->Print(variables_,
+ "clear_$oneof_name$();\n"
+ "DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n"
+ " $type$, $wire_format_field_type$>(\n"
+ " input, &$oneof_prefix$$name$_)));\n"
+ "set_has_$name$();\n");
+}
+
+// ===================================================================
+
+RepeatedPrimitiveFieldGenerator::
+RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : descriptor_(descriptor) {
+ SetPrimitiveVariables(descriptor, &variables_, options);
+
+ if (descriptor->options().packed()) {
+ variables_["packed_reader"] = "ReadPackedPrimitive";
+ variables_["repeated_reader"] = "ReadRepeatedPrimitiveNoInline";
+ } else {
+ variables_["packed_reader"] = "ReadPackedPrimitiveNoInline";
+ variables_["repeated_reader"] = "ReadRepeatedPrimitive";
+ }
+}
+
+RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {}
+
+void RepeatedPrimitiveFieldGenerator::
+GeneratePrivateMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "::google::protobuf::RepeatedField< $type$ > $name$_;\n");
+ if (descriptor_->options().packed() && HasGeneratedMethods(descriptor_->file())) {
+ printer->Print(variables_,
+ "mutable int _$name$_cached_byte_size_;\n");
+ }
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateAccessorDeclarations(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline $type$ $name$(int index) const$deprecation$;\n"
+ "inline void set_$name$(int index, $type$ value)$deprecation$;\n"
+ "inline void add_$name$($type$ value)$deprecation$;\n");
+ printer->Print(variables_,
+ "inline const ::google::protobuf::RepeatedField< $type$ >&\n"
+ " $name$() const$deprecation$;\n"
+ "inline ::google::protobuf::RepeatedField< $type$ >*\n"
+ " mutable_$name$()$deprecation$;\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline $type$ $classname$::$name$(int index) const {\n"
+ " // @@protoc_insertion_point(field_get:$full_name$)\n"
+ " return $name$_.Get(index);\n"
+ "}\n"
+ "inline void $classname$::set_$name$(int index, $type$ value) {\n"
+ " $name$_.Set(index, value);\n"
+ " // @@protoc_insertion_point(field_set:$full_name$)\n"
+ "}\n"
+ "inline void $classname$::add_$name$($type$ value) {\n"
+ " $name$_.Add(value);\n"
+ " // @@protoc_insertion_point(field_add:$full_name$)\n"
+ "}\n");
+ printer->Print(variables_,
+ "inline const ::google::protobuf::RepeatedField< $type$ >&\n"
+ "$classname$::$name$() const {\n"
+ " // @@protoc_insertion_point(field_list:$full_name$)\n"
+ " return $name$_;\n"
+ "}\n"
+ "inline ::google::protobuf::RepeatedField< $type$ >*\n"
+ "$classname$::mutable_$name$() {\n"
+ " // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
+ " return &$name$_;\n"
+ "}\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_.Clear();\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateSwappingCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_.Swap(&other->$name$_);\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+ // Not needed for repeated fields.
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+ printer->Print(variables_,
+ "DO_((::google::protobuf::internal::WireFormatLite::$repeated_reader$<\n"
+ " $type$, $wire_format_field_type$>(\n"
+ " $tag_size$, $tag$, input, this->mutable_$name$())));\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const {
+ printer->Print(variables_,
+ "DO_((::google::protobuf::internal::WireFormatLite::$packed_reader$<\n"
+ " $type$, $wire_format_field_type$>(\n"
+ " input, this->mutable_$name$())));\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+ if (descriptor_->options().packed()) {
+ // Write the tag and the size.
+ printer->Print(variables_,
+ "if (this->$name$_size() > 0) {\n"
+ " ::google::protobuf::internal::WireFormatLite::WriteTag("
+ "$number$, "
+ "::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, "
+ "output);\n"
+ " output->WriteVarint32(_$name$_cached_byte_size_);\n"
+ "}\n");
+ }
+ printer->Print(variables_,
+ "for (int i = 0; i < this->$name$_size(); i++) {\n");
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ " ::google::protobuf::internal::WireFormatLite::Write$declared_type$NoTag(\n"
+ " this->$name$(i), output);\n");
+ } else {
+ printer->Print(variables_,
+ " ::google::protobuf::internal::WireFormatLite::Write$declared_type$(\n"
+ " $number$, this->$name$(i), output);\n");
+ }
+ printer->Print("}\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
+ if (descriptor_->options().packed()) {
+ // Write the tag and the size.
+ printer->Print(variables_,
+ "if (this->$name$_size() > 0) {\n"
+ " target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(\n"
+ " $number$,\n"
+ " ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,\n"
+ " target);\n"
+ " target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(\n"
+ " _$name$_cached_byte_size_, target);\n"
+ "}\n");
+ }
+ printer->Print(variables_,
+ "for (int i = 0; i < this->$name$_size(); i++) {\n");
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ " target = ::google::protobuf::internal::WireFormatLite::\n"
+ " Write$declared_type$NoTagToArray(this->$name$(i), target);\n");
+ } else {
+ printer->Print(variables_,
+ " target = ::google::protobuf::internal::WireFormatLite::\n"
+ " Write$declared_type$ToArray($number$, this->$name$(i), target);\n");
+ }
+ printer->Print("}\n");
+}
+
+void RepeatedPrimitiveFieldGenerator::
+GenerateByteSize(io::Printer* printer) const {
+ printer->Print(variables_,
+ "{\n"
+ " int data_size = 0;\n");
+ printer->Indent();
+ int fixed_size = FixedSize(descriptor_->type());
+ if (fixed_size == -1) {
+ printer->Print(variables_,
+ "for (int i = 0; i < this->$name$_size(); i++) {\n"
+ " data_size += ::google::protobuf::internal::WireFormatLite::\n"
+ " $declared_type$Size(this->$name$(i));\n"
+ "}\n");
+ } else {
+ printer->Print(variables_,
+ "data_size = $fixed_size$ * this->$name$_size();\n");
+ }
+
+ if (descriptor_->options().packed()) {
+ printer->Print(variables_,
+ "if (data_size > 0) {\n"
+ " total_size += $tag_size$ +\n"
+ " ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);\n"
+ "}\n"
+ "GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n"
+ "_$name$_cached_byte_size_ = data_size;\n"
+ "GOOGLE_SAFE_CONCURRENT_WRITES_END();\n"
+ "total_size += data_size;\n");
+ } else {
+ printer->Print(variables_,
+ "total_size += $tag_size$ * this->$name$_size() + data_size;\n");
+ }
+ printer->Outdent();
+ printer->Print("}\n");
+}
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_primitive_field.h b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_primitive_field.h
new file mode 100644
index 00000000000..34fbf6d23b9
--- /dev/null
+++ b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_primitive_field.h
@@ -0,0 +1,123 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_PRIMITIVE_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_PRIMITIVE_FIELD_H__
+
+#include <map>
+#include <string>
+#include "google/protobuf/compiler/cpp/cpp_field.h"
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class PrimitiveFieldGenerator : public FieldGenerator {
+ public:
+ explicit PrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ ~PrimitiveFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ void GeneratePrivateMembers(io::Printer* printer) const;
+ void GenerateAccessorDeclarations(io::Printer* printer) const;
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+ void GenerateClearingCode(io::Printer* printer) const;
+ void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateSwappingCode(io::Printer* printer) const;
+ void GenerateConstructorCode(io::Printer* printer) const;
+ void GenerateMergeFromCodedStream(io::Printer* printer) const;
+ void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
+ void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
+ void GenerateByteSize(io::Printer* printer) const;
+
+ protected:
+ const FieldDescriptor* descriptor_;
+ map<string, string> variables_;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator);
+};
+
+class PrimitiveOneofFieldGenerator : public PrimitiveFieldGenerator {
+ public:
+ explicit PrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ ~PrimitiveOneofFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+ void GenerateClearingCode(io::Printer* printer) const;
+ void GenerateSwappingCode(io::Printer* printer) const;
+ void GenerateConstructorCode(io::Printer* printer) const;
+ void GenerateMergeFromCodedStream(io::Printer* printer) const;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveOneofFieldGenerator);
+};
+
+class RepeatedPrimitiveFieldGenerator : public FieldGenerator {
+ public:
+ explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ ~RepeatedPrimitiveFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ void GeneratePrivateMembers(io::Printer* printer) const;
+ void GenerateAccessorDeclarations(io::Printer* printer) const;
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+ void GenerateClearingCode(io::Printer* printer) const;
+ void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateSwappingCode(io::Printer* printer) const;
+ void GenerateConstructorCode(io::Printer* printer) const;
+ void GenerateMergeFromCodedStream(io::Printer* printer) const;
+ void GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const;
+ void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
+ void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
+ void GenerateByteSize(io::Printer* printer) const;
+
+ private:
+ const FieldDescriptor* descriptor_;
+ map<string, string> variables_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPrimitiveFieldGenerator);
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_PRIMITIVE_FIELD_H__
diff --git a/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_string_field.cc b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_string_field.cc
new file mode 100644
index 00000000000..0516aef3000
--- /dev/null
+++ b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_string_field.cc
@@ -0,0 +1,642 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include "google/protobuf/compiler/cpp/cpp_string_field.h"
+#include "google/protobuf/compiler/cpp/cpp_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 cpp {
+
+namespace {
+
+void SetStringVariables(const FieldDescriptor* descriptor,
+ map<string, string>* variables,
+ const Options& options) {
+ SetCommonFieldVariables(descriptor, variables, options);
+ (*variables)["default"] = DefaultValue(descriptor);
+ (*variables)["default_length"] =
+ SimpleItoa(descriptor->default_value_string().length());
+ (*variables)["default_variable"] = descriptor->default_value_string().empty()
+ ? "&::google::protobuf::internal::GetEmptyStringAlreadyInited()"
+ : "_default_" + FieldName(descriptor) + "_";
+ (*variables)["pointer_type"] =
+ descriptor->type() == FieldDescriptor::TYPE_BYTES ? "void" : "char";
+ // NOTE: Escaped here to unblock proto1->proto2 migration.
+ // TODO(liujisi): Extend this to apply for other conflicting methods.
+ (*variables)["release_name"] =
+ SafeFunctionName(descriptor->containing_type(),
+ descriptor, "release_");
+ (*variables)["full_name"] = descriptor->full_name();
+}
+
+} // namespace
+
+// ===================================================================
+
+StringFieldGenerator::
+StringFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : descriptor_(descriptor) {
+ SetStringVariables(descriptor, &variables_, options);
+}
+
+StringFieldGenerator::~StringFieldGenerator() {}
+
+void StringFieldGenerator::
+GeneratePrivateMembers(io::Printer* printer) const {
+ printer->Print(variables_, "::std::string* $name$_;\n");
+}
+
+void StringFieldGenerator::
+GenerateStaticMembers(io::Printer* printer) const {
+ if (!descriptor_->default_value_string().empty()) {
+ printer->Print(variables_, "static ::std::string* $default_variable$;\n");
+ }
+}
+
+void StringFieldGenerator::
+GenerateAccessorDeclarations(io::Printer* printer) const {
+ // If we're using StringFieldGenerator for a field with a ctype, it's
+ // because that ctype isn't actually implemented. In particular, this is
+ // true of ctype=CORD and ctype=STRING_PIECE in the open source release.
+ // We aren't releasing Cord because it has too many Google-specific
+ // dependencies and we aren't releasing StringPiece because it's hardly
+ // useful outside of Google and because it would get confusing to have
+ // multiple instances of the StringPiece class in different libraries (PCRE
+ // already includes it for their C++ bindings, which came from Google).
+ //
+ // In any case, we make all the accessors private while still actually
+ // using a string to represent the field internally. This way, we can
+ // guarantee that if we do ever implement the ctype, it won't break any
+ // existing users who might be -- for whatever reason -- already using .proto
+ // files that applied the ctype. The field can still be accessed via the
+ // reflection interface since the reflection interface is independent of
+ // the string's underlying representation.
+ if (descriptor_->options().ctype() != FieldOptions::STRING) {
+ printer->Outdent();
+ printer->Print(
+ " private:\n"
+ " // Hidden due to unknown ctype option.\n");
+ printer->Indent();
+ }
+
+ printer->Print(variables_,
+ "inline const ::std::string& $name$() const$deprecation$;\n"
+ "inline void set_$name$(const ::std::string& value)$deprecation$;\n"
+ "inline void set_$name$(const char* value)$deprecation$;\n"
+ "inline void set_$name$(const $pointer_type$* value, size_t size)"
+ "$deprecation$;\n"
+ "inline ::std::string* mutable_$name$()$deprecation$;\n"
+ "inline ::std::string* $release_name$()$deprecation$;\n"
+ "inline void set_allocated_$name$(::std::string* $name$)$deprecation$;\n");
+
+
+ if (descriptor_->options().ctype() != FieldOptions::STRING) {
+ printer->Outdent();
+ printer->Print(" public:\n");
+ printer->Indent();
+ }
+}
+
+void StringFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline const ::std::string& $classname$::$name$() const {\n"
+ " // @@protoc_insertion_point(field_get:$full_name$)\n"
+ " return *$name$_;\n"
+ "}\n"
+ "inline void $classname$::set_$name$(const ::std::string& value) {\n"
+ " set_has_$name$();\n"
+ " if ($name$_ == $default_variable$) {\n"
+ " $name$_ = new ::std::string;\n"
+ " }\n"
+ " $name$_->assign(value);\n"
+ " // @@protoc_insertion_point(field_set:$full_name$)\n"
+ "}\n"
+ "inline void $classname$::set_$name$(const char* value) {\n"
+ " set_has_$name$();\n"
+ " if ($name$_ == $default_variable$) {\n"
+ " $name$_ = new ::std::string;\n"
+ " }\n"
+ " $name$_->assign(value);\n"
+ " // @@protoc_insertion_point(field_set_char:$full_name$)\n"
+ "}\n"
+ "inline "
+ "void $classname$::set_$name$(const $pointer_type$* value, size_t size) {\n"
+ " set_has_$name$();\n"
+ " if ($name$_ == $default_variable$) {\n"
+ " $name$_ = new ::std::string;\n"
+ " }\n"
+ " $name$_->assign(reinterpret_cast<const char*>(value), size);\n"
+ " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
+ "}\n"
+ "inline ::std::string* $classname$::mutable_$name$() {\n"
+ " set_has_$name$();\n"
+ " if ($name$_ == $default_variable$) {\n");
+ if (descriptor_->default_value_string().empty()) {
+ printer->Print(variables_,
+ " $name$_ = new ::std::string;\n");
+ } else {
+ printer->Print(variables_,
+ " $name$_ = new ::std::string(*$default_variable$);\n");
+ }
+ printer->Print(variables_,
+ " }\n"
+ " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
+ " return $name$_;\n"
+ "}\n"
+ "inline ::std::string* $classname$::$release_name$() {\n"
+ " clear_has_$name$();\n"
+ " if ($name$_ == $default_variable$) {\n"
+ " return NULL;\n"
+ " } else {\n"
+ " ::std::string* temp = $name$_;\n"
+ " $name$_ = const_cast< ::std::string*>($default_variable$);\n"
+ " return temp;\n"
+ " }\n"
+ "}\n"
+ "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n"
+ " if ($name$_ != $default_variable$) {\n"
+ " delete $name$_;\n"
+ " }\n"
+ " if ($name$) {\n"
+ " set_has_$name$();\n"
+ " $name$_ = $name$;\n"
+ " } else {\n"
+ " clear_has_$name$();\n"
+ " $name$_ = const_cast< ::std::string*>($default_variable$);\n"
+ " }\n"
+ " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
+ "}\n");
+}
+
+void StringFieldGenerator::
+GenerateNonInlineAccessorDefinitions(io::Printer* printer) const {
+ if (!descriptor_->default_value_string().empty()) {
+ // Initialized in GenerateDefaultInstanceAllocator.
+ printer->Print(variables_,
+ "::std::string* $classname$::$default_variable$ = NULL;\n");
+ }
+}
+
+void StringFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+ if (descriptor_->default_value_string().empty()) {
+ printer->Print(variables_,
+ "if ($name$_ != $default_variable$) {\n"
+ " $name$_->clear();\n"
+ "}\n");
+ } else {
+ printer->Print(variables_,
+ "if ($name$_ != $default_variable$) {\n"
+ " $name$_->assign(*$default_variable$);\n"
+ "}\n");
+ }
+}
+
+void StringFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+ printer->Print(variables_, "set_$name$(from.$name$());\n");
+}
+
+void StringFieldGenerator::
+GenerateSwappingCode(io::Printer* printer) const {
+ printer->Print(variables_, "std::swap($name$_, other->$name$_);\n");
+}
+
+void StringFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "$name$_ = const_cast< ::std::string*>($default_variable$);\n");
+}
+
+void StringFieldGenerator::
+GenerateDestructorCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if ($name$_ != $default_variable$) {\n"
+ " delete $name$_;\n"
+ "}\n");
+}
+
+void StringFieldGenerator::
+GenerateDefaultInstanceAllocator(io::Printer* printer) const {
+ if (!descriptor_->default_value_string().empty()) {
+ printer->Print(variables_,
+ "$classname$::$default_variable$ =\n"
+ " new ::std::string($default$, $default_length$);\n");
+ }
+}
+
+void StringFieldGenerator::
+GenerateShutdownCode(io::Printer* printer) const {
+ if (!descriptor_->default_value_string().empty()) {
+ printer->Print(variables_,
+ "delete $classname$::$default_variable$;\n");
+ }
+}
+
+void StringFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+ printer->Print(variables_,
+ "DO_(::google::protobuf::internal::WireFormatLite::Read$declared_type$(\n"
+ " input, this->mutable_$name$()));\n");
+ if (HasUtf8Verification(descriptor_->file()) &&
+ descriptor_->type() == FieldDescriptor::TYPE_STRING) {
+ printer->Print(variables_,
+ "::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n"
+ " this->$name$().data(), this->$name$().length(),\n"
+ " ::google::protobuf::internal::WireFormat::PARSE,\n"
+ " \"$name$\");\n");
+ }
+}
+
+void StringFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+ if (HasUtf8Verification(descriptor_->file()) &&
+ descriptor_->type() == FieldDescriptor::TYPE_STRING) {
+ printer->Print(variables_,
+ "::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n"
+ " this->$name$().data(), this->$name$().length(),\n"
+ " ::google::protobuf::internal::WireFormat::SERIALIZE,\n"
+ " \"$name$\");\n");
+ }
+ printer->Print(variables_,
+ "::google::protobuf::internal::WireFormatLite::Write$declared_type$MaybeAliased(\n"
+ " $number$, this->$name$(), output);\n");
+}
+
+void StringFieldGenerator::
+GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
+ if (HasUtf8Verification(descriptor_->file()) &&
+ descriptor_->type() == FieldDescriptor::TYPE_STRING) {
+ printer->Print(variables_,
+ "::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n"
+ " this->$name$().data(), this->$name$().length(),\n"
+ " ::google::protobuf::internal::WireFormat::SERIALIZE,\n"
+ " \"$name$\");\n");
+ }
+ printer->Print(variables_,
+ "target =\n"
+ " ::google::protobuf::internal::WireFormatLite::Write$declared_type$ToArray(\n"
+ " $number$, this->$name$(), target);\n");
+}
+
+void StringFieldGenerator::
+GenerateByteSize(io::Printer* printer) const {
+ printer->Print(variables_,
+ "total_size += $tag_size$ +\n"
+ " ::google::protobuf::internal::WireFormatLite::$declared_type$Size(\n"
+ " this->$name$());\n");
+}
+
+// ===================================================================
+
+StringOneofFieldGenerator::
+StringOneofFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : StringFieldGenerator(descriptor, options) {
+ SetCommonOneofFieldVariables(descriptor, &variables_);
+}
+
+StringOneofFieldGenerator::~StringOneofFieldGenerator() {}
+
+void StringOneofFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline const ::std::string& $classname$::$name$() const {\n"
+ " if (has_$name$()) {\n"
+ " return *$oneof_prefix$$name$_;\n"
+ " }\n");
+ if (descriptor_->default_value_string().empty()) {
+ printer->Print(variables_,
+ " return ::google::protobuf::internal::GetEmptyStringAlreadyInited();\n");
+ } else {
+ printer->Print(variables_,
+ " return *$default_variable$;\n");
+ }
+ printer->Print(variables_,
+ "}\n"
+ "inline void $classname$::set_$name$(const ::std::string& value) {\n"
+ " if (!has_$name$()) {\n"
+ " clear_$oneof_name$();\n"
+ " set_has_$name$();\n"
+ " $oneof_prefix$$name$_ = new ::std::string;\n"
+ " }\n"
+ " $oneof_prefix$$name$_->assign(value);\n"
+ "}\n"
+ "inline void $classname$::set_$name$(const char* value) {\n"
+ " if (!has_$name$()) {\n"
+ " clear_$oneof_name$();\n"
+ " set_has_$name$();\n"
+ " $oneof_prefix$$name$_ = new ::std::string;\n"
+ " }\n"
+ " $oneof_prefix$$name$_->assign(value);\n"
+ "}\n"
+ "inline "
+ "void $classname$::set_$name$(const $pointer_type$* value, size_t size) {\n"
+ " if (!has_$name$()) {\n"
+ " clear_$oneof_name$();\n"
+ " set_has_$name$();\n"
+ " $oneof_prefix$$name$_ = new ::std::string;\n"
+ " }\n"
+ " $oneof_prefix$$name$_->assign(\n"
+ " reinterpret_cast<const char*>(value), size);\n"
+ "}\n"
+ "inline ::std::string* $classname$::mutable_$name$() {\n"
+ " if (!has_$name$()) {\n"
+ " clear_$oneof_name$();\n"
+ " set_has_$name$();\n");
+ if (descriptor_->default_value_string().empty()) {
+ printer->Print(variables_,
+ " $oneof_prefix$$name$_ = new ::std::string;\n");
+ } else {
+ printer->Print(variables_,
+ " $oneof_prefix$$name$_ = new ::std::string(*$default_variable$);\n");
+ }
+ printer->Print(variables_,
+ " }\n"
+ " return $oneof_prefix$$name$_;\n"
+ "}\n"
+ "inline ::std::string* $classname$::$release_name$() {\n"
+ " if (has_$name$()) {\n"
+ " clear_has_$oneof_name$();\n"
+ " ::std::string* temp = $oneof_prefix$$name$_;\n"
+ " $oneof_prefix$$name$_ = NULL;\n"
+ " return temp;\n"
+ " } else {\n"
+ " return NULL;\n"
+ " }\n"
+ "}\n"
+ "inline void $classname$::set_allocated_$name$(::std::string* $name$) {\n"
+ " clear_$oneof_name$();\n"
+ " if ($name$) {\n"
+ " set_has_$name$();\n"
+ " $oneof_prefix$$name$_ = $name$;\n"
+ " }\n"
+ "}\n");
+}
+
+void StringOneofFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "delete $oneof_prefix$$name$_;\n");
+}
+
+void StringOneofFieldGenerator::
+GenerateSwappingCode(io::Printer* printer) const {
+ // Don't print any swapping code. Swapping the union will swap this field.
+}
+
+void StringOneofFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+ if (!descriptor_->default_value_string().empty()) {
+ printer->Print(variables_,
+ " $classname$_default_oneof_instance_->$name$_ = "
+ "$classname$::$default_variable$;\n");
+ } else {
+ printer->Print(variables_,
+ " $classname$_default_oneof_instance_->$name$_ = "
+ "$default_variable$;\n");
+ }
+}
+
+void StringOneofFieldGenerator::
+GenerateDestructorCode(io::Printer* printer) const {
+ printer->Print(variables_,
+ "if (has_$name$()) {\n"
+ " delete $oneof_prefix$$name$_;\n"
+ "}\n");
+}
+
+// ===================================================================
+
+RepeatedStringFieldGenerator::
+RepeatedStringFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : descriptor_(descriptor) {
+ SetStringVariables(descriptor, &variables_, options);
+}
+
+RepeatedStringFieldGenerator::~RepeatedStringFieldGenerator() {}
+
+void RepeatedStringFieldGenerator::
+GeneratePrivateMembers(io::Printer* printer) const {
+ printer->Print(variables_,
+ "::google::protobuf::RepeatedPtrField< ::std::string> $name$_;\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateAccessorDeclarations(io::Printer* printer) const {
+ // See comment above about unknown ctypes.
+ if (descriptor_->options().ctype() != FieldOptions::STRING) {
+ printer->Outdent();
+ printer->Print(
+ " private:\n"
+ " // Hidden due to unknown ctype option.\n");
+ printer->Indent();
+ }
+
+ printer->Print(variables_,
+ "inline const ::std::string& $name$(int index) const$deprecation$;\n"
+ "inline ::std::string* mutable_$name$(int index)$deprecation$;\n"
+ "inline void set_$name$(int index, const ::std::string& value)$deprecation$;\n"
+ "inline void set_$name$(int index, const char* value)$deprecation$;\n"
+ "inline "
+ "void set_$name$(int index, const $pointer_type$* value, size_t size)"
+ "$deprecation$;\n"
+ "inline ::std::string* add_$name$()$deprecation$;\n"
+ "inline void add_$name$(const ::std::string& value)$deprecation$;\n"
+ "inline void add_$name$(const char* value)$deprecation$;\n"
+ "inline void add_$name$(const $pointer_type$* value, size_t size)"
+ "$deprecation$;\n");
+
+ printer->Print(variables_,
+ "inline const ::google::protobuf::RepeatedPtrField< ::std::string>& $name$() const"
+ "$deprecation$;\n"
+ "inline ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_$name$()"
+ "$deprecation$;\n");
+
+ if (descriptor_->options().ctype() != FieldOptions::STRING) {
+ printer->Outdent();
+ printer->Print(" public:\n");
+ printer->Indent();
+ }
+}
+
+void RepeatedStringFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer) const {
+ printer->Print(variables_,
+ "inline const ::std::string& $classname$::$name$(int index) const {\n"
+ " // @@protoc_insertion_point(field_get:$full_name$)\n"
+ " return $name$_.$cppget$(index);\n"
+ "}\n"
+ "inline ::std::string* $classname$::mutable_$name$(int index) {\n"
+ " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
+ " return $name$_.Mutable(index);\n"
+ "}\n"
+ "inline void $classname$::set_$name$(int index, const ::std::string& value) {\n"
+ " // @@protoc_insertion_point(field_set:$full_name$)\n"
+ " $name$_.Mutable(index)->assign(value);\n"
+ "}\n"
+ "inline void $classname$::set_$name$(int index, const char* value) {\n"
+ " $name$_.Mutable(index)->assign(value);\n"
+ " // @@protoc_insertion_point(field_set_char:$full_name$)\n"
+ "}\n"
+ "inline void "
+ "$classname$::set_$name$"
+ "(int index, const $pointer_type$* value, size_t size) {\n"
+ " $name$_.Mutable(index)->assign(\n"
+ " reinterpret_cast<const char*>(value), size);\n"
+ " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
+ "}\n"
+ "inline ::std::string* $classname$::add_$name$() {\n"
+ " return $name$_.Add();\n"
+ "}\n"
+ "inline void $classname$::add_$name$(const ::std::string& value) {\n"
+ " $name$_.Add()->assign(value);\n"
+ " // @@protoc_insertion_point(field_add:$full_name$)\n"
+ "}\n"
+ "inline void $classname$::add_$name$(const char* value) {\n"
+ " $name$_.Add()->assign(value);\n"
+ " // @@protoc_insertion_point(field_add_char:$full_name$)\n"
+ "}\n"
+ "inline void "
+ "$classname$::add_$name$(const $pointer_type$* value, size_t size) {\n"
+ " $name$_.Add()->assign(reinterpret_cast<const char*>(value), size);\n"
+ " // @@protoc_insertion_point(field_add_pointer:$full_name$)\n"
+ "}\n");
+ printer->Print(variables_,
+ "inline const ::google::protobuf::RepeatedPtrField< ::std::string>&\n"
+ "$classname$::$name$() const {\n"
+ " // @@protoc_insertion_point(field_list:$full_name$)\n"
+ " return $name$_;\n"
+ "}\n"
+ "inline ::google::protobuf::RepeatedPtrField< ::std::string>*\n"
+ "$classname$::mutable_$name$() {\n"
+ " // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
+ " return &$name$_;\n"
+ "}\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateClearingCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_.Clear();\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateMergingCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateSwappingCode(io::Printer* printer) const {
+ printer->Print(variables_, "$name$_.Swap(&other->$name$_);\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateConstructorCode(io::Printer* printer) const {
+ // Not needed for repeated fields.
+}
+
+void RepeatedStringFieldGenerator::
+GenerateMergeFromCodedStream(io::Printer* printer) const {
+ printer->Print(variables_,
+ "DO_(::google::protobuf::internal::WireFormatLite::Read$declared_type$(\n"
+ " input, this->add_$name$()));\n");
+ if (HasUtf8Verification(descriptor_->file()) &&
+ descriptor_->type() == FieldDescriptor::TYPE_STRING) {
+ printer->Print(variables_,
+ "::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n"
+ " this->$name$(this->$name$_size() - 1).data(),\n"
+ " this->$name$(this->$name$_size() - 1).length(),\n"
+ " ::google::protobuf::internal::WireFormat::PARSE,\n"
+ " \"$name$\");\n");
+ }
+}
+
+void RepeatedStringFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+ printer->Print(variables_,
+ "for (int i = 0; i < this->$name$_size(); i++) {\n");
+ if (HasUtf8Verification(descriptor_->file()) &&
+ descriptor_->type() == FieldDescriptor::TYPE_STRING) {
+ printer->Print(variables_,
+ "::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n"
+ " this->$name$(i).data(), this->$name$(i).length(),\n"
+ " ::google::protobuf::internal::WireFormat::SERIALIZE,\n"
+ " \"$name$\");\n");
+ }
+ printer->Print(variables_,
+ " ::google::protobuf::internal::WireFormatLite::Write$declared_type$(\n"
+ " $number$, this->$name$(i), output);\n"
+ "}\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
+ printer->Print(variables_,
+ "for (int i = 0; i < this->$name$_size(); i++) {\n");
+ if (HasUtf8Verification(descriptor_->file()) &&
+ descriptor_->type() == FieldDescriptor::TYPE_STRING) {
+ printer->Print(variables_,
+ " ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n"
+ " this->$name$(i).data(), this->$name$(i).length(),\n"
+ " ::google::protobuf::internal::WireFormat::SERIALIZE,\n"
+ " \"$name$\");\n");
+ }
+ printer->Print(variables_,
+ " target = ::google::protobuf::internal::WireFormatLite::\n"
+ " Write$declared_type$ToArray($number$, this->$name$(i), target);\n"
+ "}\n");
+}
+
+void RepeatedStringFieldGenerator::
+GenerateByteSize(io::Printer* printer) const {
+ printer->Print(variables_,
+ "total_size += $tag_size$ * this->$name$_size();\n"
+ "for (int i = 0; i < this->$name$_size(); i++) {\n"
+ " total_size += ::google::protobuf::internal::WireFormatLite::$declared_type$Size(\n"
+ " this->$name$(i));\n"
+ "}\n");
+}
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_string_field.h b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_string_field.h
new file mode 100644
index 00000000000..482d817e7a6
--- /dev/null
+++ b/contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_string_field.h
@@ -0,0 +1,127 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_STRING_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_CPP_STRING_FIELD_H__
+
+#include <map>
+#include <string>
+#include "google/protobuf/compiler/cpp/cpp_field.h"
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace cpp {
+
+class StringFieldGenerator : public FieldGenerator {
+ public:
+ explicit StringFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ ~StringFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ void GeneratePrivateMembers(io::Printer* printer) const;
+ void GenerateStaticMembers(io::Printer* printer) const;
+ void GenerateAccessorDeclarations(io::Printer* printer) const;
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+ void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const;
+ void GenerateClearingCode(io::Printer* printer) const;
+ void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateSwappingCode(io::Printer* printer) const;
+ void GenerateConstructorCode(io::Printer* printer) const;
+ void GenerateDestructorCode(io::Printer* printer) const;
+ void GenerateDefaultInstanceAllocator(io::Printer* printer) const;
+ void GenerateShutdownCode(io::Printer* printer) const;
+ void GenerateMergeFromCodedStream(io::Printer* printer) const;
+ void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
+ void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
+ void GenerateByteSize(io::Printer* printer) const;
+
+ protected:
+ const FieldDescriptor* descriptor_;
+ map<string, string> variables_;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringFieldGenerator);
+};
+
+class StringOneofFieldGenerator : public StringFieldGenerator {
+ public:
+ explicit StringOneofFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ ~StringOneofFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+ void GenerateClearingCode(io::Printer* printer) const;
+ void GenerateSwappingCode(io::Printer* printer) const;
+ void GenerateConstructorCode(io::Printer* printer) const;
+ void GenerateDestructorCode(io::Printer* printer) const;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringOneofFieldGenerator);
+};
+
+class RepeatedStringFieldGenerator : public FieldGenerator {
+ public:
+ explicit RepeatedStringFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ ~RepeatedStringFieldGenerator();
+
+ // implements FieldGenerator ---------------------------------------
+ void GeneratePrivateMembers(io::Printer* printer) const;
+ void GenerateAccessorDeclarations(io::Printer* printer) const;
+ void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
+ void GenerateClearingCode(io::Printer* printer) const;
+ void GenerateMergingCode(io::Printer* printer) const;
+ void GenerateSwappingCode(io::Printer* printer) const;
+ void GenerateConstructorCode(io::Printer* printer) const;
+ void GenerateMergeFromCodedStream(io::Printer* printer) const;
+ void GenerateSerializeWithCachedSizes(io::Printer* printer) const;
+ void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
+ void GenerateByteSize(io::Printer* printer) const;
+
+ private:
+ const FieldDescriptor* descriptor_;
+ map<string, string> variables_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedStringFieldGenerator);
+};
+
+} // namespace cpp
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_CPP_STRING_FIELD_H__
diff --git a/contrib/protoc-bnet/google/protobuf/stubs/hash.h b/contrib/protoc-bnet/google/protobuf/stubs/hash.h
new file mode 100644
index 00000000000..5b6a073dd53
--- /dev/null
+++ b/contrib/protoc-bnet/google/protobuf/stubs/hash.h
@@ -0,0 +1,232 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// Deals with the fact that hash_map is not defined everywhere.
+
+#ifndef GOOGLE_PROTOBUF_STUBS_HASH_H__
+#define GOOGLE_PROTOBUF_STUBS_HASH_H__
+
+#include <string.h>
+#include <google/protobuf/stubs/common.h>
+#include "config.h"
+
+#if defined(HAVE_HASH_MAP) && defined(HAVE_HASH_SET)
+#include HASH_MAP_H
+#include HASH_SET_H
+#else
+#define MISSING_HASH
+#include <map>
+#include <set>
+#endif
+
+namespace google {
+namespace protobuf {
+
+#ifdef MISSING_HASH
+
+// This system doesn't have hash_map or hash_set. Emulate them using map and
+// set.
+
+// Make hash<T> be the same as less<T>. Note that everywhere where custom
+// hash functions are defined in the protobuf code, they are also defined such
+// that they can be used as "less" functions, which is required by MSVC anyway.
+template <typename Key>
+struct hash {
+ // Dummy, just to make derivative hash functions compile.
+ int operator()(const Key& key) {
+ GOOGLE_LOG(FATAL) << "Should never be called.";
+ return 0;
+ }
+
+ inline bool operator()(const Key& a, const Key& b) const {
+ return a < b;
+ }
+};
+
+// Make sure char* is compared by value.
+template <>
+struct hash<const char*> {
+ // Dummy, just to make derivative hash functions compile.
+ int operator()(const char* key) {
+ GOOGLE_LOG(FATAL) << "Should never be called.";
+ return 0;
+ }
+
+ inline bool operator()(const char* a, const char* b) const {
+ return strcmp(a, b) < 0;
+ }
+};
+
+template <typename Key, typename Data,
+ typename HashFcn = hash<Key>,
+ typename EqualKey = int >
+class hash_map : public std::map<Key, Data, HashFcn> {
+ public:
+ hash_map(int = 0) {}
+};
+
+template <typename Key,
+ typename HashFcn = hash<Key>,
+ typename EqualKey = int >
+class hash_set : public std::set<Key, HashFcn> {
+ public:
+ hash_set(int = 0) {}
+};
+
+#elif defined(_MSC_VER) && !defined(_STLPORT_VERSION)
+
+template <typename Key>
+struct hash : public HASH_NAMESPACE::hash_compare<Key> {
+};
+
+// MSVC's hash_compare<const char*> hashes based on the string contents but
+// compares based on the string pointer. WTF?
+class CstringLess {
+ public:
+ inline bool operator()(const char* a, const char* b) const {
+ return strcmp(a, b) < 0;
+ }
+};
+
+template <>
+struct hash<const char*>
+ : public HASH_NAMESPACE::hash_compare<const char*, CstringLess> {
+};
+
+template <typename Key, typename Data,
+ typename HashFcn = hash<Key>,
+ typename EqualKey = int >
+class hash_map : public HASH_NAMESPACE::hash_map<
+ Key, Data, HashFcn> {
+ public:
+ hash_map(int = 0) {}
+};
+
+template <typename Key,
+ typename HashFcn = hash<Key>,
+ typename EqualKey = int >
+class hash_set : public HASH_NAMESPACE::hash_set<
+ Key, HashFcn> {
+ public:
+ hash_set(int = 0) {}
+};
+
+#else
+
+template <typename Key>
+struct hash : public HASH_NAMESPACE::hash<Key> {
+};
+
+template <typename Key>
+struct hash<const Key*> {
+ inline size_t operator()(const Key* key) const {
+ return reinterpret_cast<size_t>(key);
+ }
+};
+
+// Unlike the old SGI version, the TR1 "hash" does not special-case char*. So,
+// we go ahead and provide our own implementation.
+template <>
+struct hash<const char*> {
+ inline size_t operator()(const char* str) const {
+ size_t result = 0;
+ for (; *str != '\0'; str++) {
+ result = 5 * result + *str;
+ }
+ return result;
+ }
+};
+
+template <typename Key, typename Data,
+ typename HashFcn = hash<Key>,
+ typename EqualKey = std::equal_to<Key> >
+class hash_map : public HASH_NAMESPACE::HASH_MAP_CLASS<
+ Key, Data, HashFcn, EqualKey> {
+ public:
+ hash_map(int = 0) {}
+};
+
+template <typename Key,
+ typename HashFcn = hash<Key>,
+ typename EqualKey = std::equal_to<Key> >
+class hash_set : public HASH_NAMESPACE::HASH_SET_CLASS<
+ Key, HashFcn, EqualKey> {
+ public:
+ hash_set(int = 0) {}
+};
+
+#endif
+
+template <>
+struct hash<string> {
+ inline size_t operator()(const string& key) const {
+ return hash<const char*>()(key.c_str());
+ }
+
+ static const size_t bucket_size = 4;
+ static const size_t min_buckets = 8;
+ inline size_t operator()(const string& a, const string& b) const {
+ return a < b;
+ }
+};
+
+template <typename First, typename Second>
+struct hash<pair<First, Second> > {
+ inline size_t operator()(const pair<First, Second>& key) const {
+ size_t first_hash = hash<First>()(key.first);
+ size_t second_hash = hash<Second>()(key.second);
+
+ // FIXME(kenton): What is the best way to compute this hash? I have
+ // no idea! This seems a bit better than an XOR.
+ return first_hash * ((1 << 16) - 1) + second_hash;
+ }
+
+ static const size_t bucket_size = 4;
+ static const size_t min_buckets = 8;
+ inline size_t operator()(const pair<First, Second>& a,
+ const pair<First, Second>& b) const {
+ return a < b;
+ }
+};
+
+// Used by GCC/SGI STL only. (Why isn't this provided by the standard
+// library? :( )
+struct streq {
+ inline bool operator()(const char* a, const char* b) const {
+ return strcmp(a, b) == 0;
+ }
+};
+
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_STUBS_HASH_H__
diff --git a/contrib/protoc-bnet/google/protobuf/stubs/strutil.cc b/contrib/protoc-bnet/google/protobuf/stubs/strutil.cc
new file mode 100644
index 00000000000..6cbbb7834eb
--- /dev/null
+++ b/contrib/protoc-bnet/google/protobuf/stubs/strutil.cc
@@ -0,0 +1,1279 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// from google3/strings/strutil.cc
+
+#include "strutil.h"
+#include <errno.h>
+#include <float.h> // FLT_DIG and DBL_DIG
+#include <limits>
+#include <limits.h>
+#include <stdio.h>
+#include <iterator>
+
+#ifdef _WIN32
+// MSVC has only _snprintf, not snprintf.
+//
+// MinGW has both snprintf and _snprintf, but they appear to be different
+// functions. The former is buggy. When invoked like so:
+// char buffer[32];
+// snprintf(buffer, 32, "%.*g\n", FLT_DIG, 1.23e10f);
+// it prints "1.23000e+10". This is plainly wrong: %g should never print
+// trailing zeros after the decimal point. For some reason this bug only
+// occurs with some input values, not all. In any case, _snprintf does the
+// right thing, so we use it.
+#define snprintf _snprintf
+#endif
+
+namespace google {
+namespace protobuf {
+
+inline bool IsNaN(double value) {
+ // NaN is never equal to anything, even itself.
+ return value != value;
+}
+
+// These are defined as macros on some platforms. #undef them so that we can
+// redefine them.
+#undef isxdigit
+#undef isprint
+
+// The definitions of these in ctype.h change based on locale. Since our
+// string manipulation is all in relation to the protocol buffer and C++
+// languages, we always want to use the C locale. So, we re-define these
+// exactly as we want them.
+inline bool isxdigit(char c) {
+ return ('0' <= c && c <= '9') ||
+ ('a' <= c && c <= 'f') ||
+ ('A' <= c && c <= 'F');
+}
+
+inline bool isprint(char c) {
+ return c >= 0x20 && c <= 0x7E;
+}
+
+// ----------------------------------------------------------------------
+// StripString
+// Replaces any occurrence of the character 'remove' (or the characters
+// in 'remove') with the character 'replacewith'.
+// ----------------------------------------------------------------------
+void StripString(string* s, const char* remove, char replacewith) {
+ const char * str_start = s->c_str();
+ const char * str = str_start;
+ for (str = strpbrk(str, remove);
+ str != NULL;
+ str = strpbrk(str + 1, remove)) {
+ (*s)[str - str_start] = replacewith;
+ }
+}
+
+// ----------------------------------------------------------------------
+// StringReplace()
+// Replace the "old" pattern with the "new" pattern in a string,
+// and append the result to "res". If replace_all is false,
+// it only replaces the first instance of "old."
+// ----------------------------------------------------------------------
+
+void StringReplace(const string& s, const string& oldsub,
+ const string& newsub, bool replace_all,
+ string* res) {
+ if (oldsub.empty()) {
+ res->append(s); // if empty, append the given string.
+ return;
+ }
+
+ string::size_type start_pos = 0;
+ string::size_type pos;
+ do {
+ pos = s.find(oldsub, start_pos);
+ if (pos == string::npos) {
+ break;
+ }
+ res->append(s, start_pos, pos - start_pos);
+ res->append(newsub);
+ start_pos = pos + oldsub.size(); // start searching again after the "old"
+ } while (replace_all);
+ res->append(s, start_pos, s.length() - start_pos);
+}
+
+// ----------------------------------------------------------------------
+// StringReplace()
+// Give me a string and two patterns "old" and "new", and I replace
+// the first instance of "old" in the string with "new", if it
+// exists. If "global" is true; call this repeatedly until it
+// fails. RETURN a new string, regardless of whether the replacement
+// happened or not.
+// ----------------------------------------------------------------------
+
+string StringReplace(const string& s, const string& oldsub,
+ const string& newsub, bool replace_all) {
+ string ret;
+ StringReplace(s, oldsub, newsub, replace_all, &ret);
+ return ret;
+}
+
+// ----------------------------------------------------------------------
+// SplitStringUsing()
+// Split a string using a character delimiter. Append the components
+// to 'result'.
+//
+// Note: For multi-character delimiters, this routine will split on *ANY* of
+// the characters in the string, not the entire string as a single delimiter.
+// ----------------------------------------------------------------------
+template <typename ITR>
+static inline
+void SplitStringToIteratorUsing(const string& full,
+ const char* delim,
+ ITR& result) {
+ // Optimize the common case where delim is a single character.
+ if (delim[0] != '\0' && delim[1] == '\0') {
+ char c = delim[0];
+ const char* p = full.data();
+ const char* end = p + full.size();
+ while (p != end) {
+ if (*p == c) {
+ ++p;
+ } else {
+ const char* start = p;
+ while (++p != end && *p != c);
+ *result++ = string(start, p - start);
+ }
+ }
+ return;
+ }
+
+ string::size_type begin_index, end_index;
+ begin_index = full.find_first_not_of(delim);
+ while (begin_index != string::npos) {
+ end_index = full.find_first_of(delim, begin_index);
+ if (end_index == string::npos) {
+ *result++ = full.substr(begin_index);
+ return;
+ }
+ *result++ = full.substr(begin_index, (end_index - begin_index));
+ begin_index = full.find_first_not_of(delim, end_index);
+ }
+}
+
+void SplitStringUsing(const string& full,
+ const char* delim,
+ vector<string>* result) {
+ back_insert_iterator< vector<string> > it(*result);
+ SplitStringToIteratorUsing(full, delim, it);
+}
+
+// Split a string using a character delimiter. Append the components
+// to 'result'. If there are consecutive delimiters, this function
+// will return corresponding empty strings. The string is split into
+// at most the specified number of pieces greedily. This means that the
+// last piece may possibly be split further. To split into as many pieces
+// as possible, specify 0 as the number of pieces.
+//
+// If "full" is the empty string, yields an empty string as the only value.
+//
+// If "pieces" is negative for some reason, it returns the whole string
+// ----------------------------------------------------------------------
+template <typename StringType, typename ITR>
+static inline
+void SplitStringToIteratorAllowEmpty(const StringType& full,
+ const char* delim,
+ int pieces,
+ ITR& result) {
+ string::size_type begin_index, end_index;
+ begin_index = 0;
+
+ for (int i = 0; (i < pieces-1) || (pieces == 0); i++) {
+ end_index = full.find_first_of(delim, begin_index);
+ if (end_index == string::npos) {
+ *result++ = full.substr(begin_index);
+ return;
+ }
+ *result++ = full.substr(begin_index, (end_index - begin_index));
+ begin_index = end_index + 1;
+ }
+ *result++ = full.substr(begin_index);
+}
+
+void SplitStringAllowEmpty(const string& full, const char* delim,
+ vector<string>* result) {
+ back_insert_iterator<vector<string> > it(*result);
+ SplitStringToIteratorAllowEmpty(full, delim, 0, it);
+}
+
+// ----------------------------------------------------------------------
+// JoinStrings()
+// This merges a vector of string components with delim inserted
+// as separaters between components.
+//
+// ----------------------------------------------------------------------
+template <class ITERATOR>
+static void JoinStringsIterator(const ITERATOR& start,
+ const ITERATOR& end,
+ const char* delim,
+ string* result) {
+ GOOGLE_CHECK(result != NULL);
+ result->clear();
+ int delim_length = strlen(delim);
+
+ // Precompute resulting length so we can reserve() memory in one shot.
+ int length = 0;
+ for (ITERATOR iter = start; iter != end; ++iter) {
+ if (iter != start) {
+ length += delim_length;
+ }
+ length += iter->size();
+ }
+ result->reserve(length);
+
+ // Now combine everything.
+ for (ITERATOR iter = start; iter != end; ++iter) {
+ if (iter != start) {
+ result->append(delim, delim_length);
+ }
+ result->append(iter->data(), iter->size());
+ }
+}
+
+void JoinStrings(const vector<string>& components,
+ const char* delim,
+ string * result) {
+ JoinStringsIterator(components.begin(), components.end(), delim, result);
+}
+
+// ----------------------------------------------------------------------
+// UnescapeCEscapeSequences()
+// This does all the unescaping that C does: \ooo, \r, \n, etc
+// Returns length of resulting string.
+// The implementation of \x parses any positive number of hex digits,
+// but it is an error if the value requires more than 8 bits, and the
+// result is truncated to 8 bits.
+//
+// The second call stores its errors in a supplied string vector.
+// If the string vector pointer is NULL, it reports the errors with LOG().
+// ----------------------------------------------------------------------
+
+#define IS_OCTAL_DIGIT(c) (((c) >= '0') && ((c) <= '7'))
+
+inline int hex_digit_to_int(char c) {
+ /* Assume ASCII. */
+ assert('0' == 0x30 && 'A' == 0x41 && 'a' == 0x61);
+ assert(isxdigit(c));
+ int x = static_cast<unsigned char>(c);
+ if (x > '9') {
+ x += 9;
+ }
+ return x & 0xf;
+}
+
+// Protocol buffers doesn't ever care about errors, but I don't want to remove
+// the code.
+#define LOG_STRING(LEVEL, VECTOR) GOOGLE_LOG_IF(LEVEL, false)
+
+int UnescapeCEscapeSequences(const char* source, char* dest) {
+ return UnescapeCEscapeSequences(source, dest, NULL);
+}
+
+int UnescapeCEscapeSequences(const char* source, char* dest,
+ vector<string> *errors) {
+ GOOGLE_DCHECK(errors == NULL) << "Error reporting not implemented.";
+
+ char* d = dest;
+ const char* p = source;
+
+ // Small optimization for case where source = dest and there's no escaping
+ while ( p == d && *p != '\0' && *p != '\\' )
+ p++, d++;
+
+ while (*p != '\0') {
+ if (*p != '\\') {
+ *d++ = *p++;
+ } else {
+ switch ( *++p ) { // skip past the '\\'
+ case '\0':
+ LOG_STRING(ERROR, errors) << "String cannot end with \\";
+ *d = '\0';
+ return d - dest; // we're done with p
+ case 'a': *d++ = '\a'; break;
+ case 'b': *d++ = '\b'; break;
+ case 'f': *d++ = '\f'; break;
+ case 'n': *d++ = '\n'; break;
+ case 'r': *d++ = '\r'; break;
+ case 't': *d++ = '\t'; break;
+ case 'v': *d++ = '\v'; break;
+ case '\\': *d++ = '\\'; break;
+ case '?': *d++ = '\?'; break; // \? Who knew?
+ case '\'': *d++ = '\''; break;
+ case '"': *d++ = '\"'; break;
+ case '0': case '1': case '2': case '3': // octal digit: 1 to 3 digits
+ case '4': case '5': case '6': case '7': {
+ char ch = *p - '0';
+ if ( IS_OCTAL_DIGIT(p[1]) )
+ ch = ch * 8 + *++p - '0';
+ if ( IS_OCTAL_DIGIT(p[1]) ) // safe (and easy) to do this twice
+ ch = ch * 8 + *++p - '0'; // now points at last digit
+ *d++ = ch;
+ break;
+ }
+ case 'x': case 'X': {
+ if (!isxdigit(p[1])) {
+ if (p[1] == '\0') {
+ LOG_STRING(ERROR, errors) << "String cannot end with \\x";
+ } else {
+ LOG_STRING(ERROR, errors) <<
+ "\\x cannot be followed by non-hex digit: \\" << *p << p[1];
+ }
+ break;
+ }
+ unsigned int ch = 0;
+ const char *hex_start = p;
+ while (isxdigit(p[1])) // arbitrarily many hex digits
+ ch = (ch << 4) + hex_digit_to_int(*++p);
+ if (ch > 0xFF)
+ LOG_STRING(ERROR, errors) << "Value of " <<
+ "\\" << string(hex_start, p+1-hex_start) << " exceeds 8 bits";
+ *d++ = ch;
+ break;
+ }
+#if 0 // TODO(kenton): Support \u and \U? Requires runetochar().
+ case 'u': {
+ // \uhhhh => convert 4 hex digits to UTF-8
+ char32 rune = 0;
+ const char *hex_start = p;
+ for (int i = 0; i < 4; ++i) {
+ if (isxdigit(p[1])) { // Look one char ahead.
+ rune = (rune << 4) + hex_digit_to_int(*++p); // Advance p.
+ } else {
+ LOG_STRING(ERROR, errors)
+ << "\\u must be followed by 4 hex digits: \\"
+ << string(hex_start, p+1-hex_start);
+ break;
+ }
+ }
+ d += runetochar(d, &rune);
+ break;
+ }
+ case 'U': {
+ // \Uhhhhhhhh => convert 8 hex digits to UTF-8
+ char32 rune = 0;
+ const char *hex_start = p;
+ for (int i = 0; i < 8; ++i) {
+ if (isxdigit(p[1])) { // Look one char ahead.
+ // Don't change rune until we're sure this
+ // is within the Unicode limit, but do advance p.
+ char32 newrune = (rune << 4) + hex_digit_to_int(*++p);
+ if (newrune > 0x10FFFF) {
+ LOG_STRING(ERROR, errors)
+ << "Value of \\"
+ << string(hex_start, p + 1 - hex_start)
+ << " exceeds Unicode limit (0x10FFFF)";
+ break;
+ } else {
+ rune = newrune;
+ }
+ } else {
+ LOG_STRING(ERROR, errors)
+ << "\\U must be followed by 8 hex digits: \\"
+ << string(hex_start, p+1-hex_start);
+ break;
+ }
+ }
+ d += runetochar(d, &rune);
+ break;
+ }
+#endif
+ default:
+ LOG_STRING(ERROR, errors) << "Unknown escape sequence: \\" << *p;
+ }
+ p++; // read past letter we escaped
+ }
+ }
+ *d = '\0';
+ return d - dest;
+}
+
+// ----------------------------------------------------------------------
+// UnescapeCEscapeString()
+// This does the same thing as UnescapeCEscapeSequences, but creates
+// a new string. The caller does not need to worry about allocating
+// a dest buffer. This should be used for non performance critical
+// tasks such as printing debug messages. It is safe for src and dest
+// to be the same.
+//
+// The second call stores its errors in a supplied string vector.
+// If the string vector pointer is NULL, it reports the errors with LOG().
+//
+// In the first and second calls, the length of dest is returned. In the
+// the third call, the new string is returned.
+// ----------------------------------------------------------------------
+int UnescapeCEscapeString(const string& src, string* dest) {
+ return UnescapeCEscapeString(src, dest, NULL);
+}
+
+int UnescapeCEscapeString(const string& src, string* dest,
+ vector<string> *errors) {
+ scoped_array<char> unescaped(new char[src.size() + 1]);
+ int len = UnescapeCEscapeSequences(src.c_str(), unescaped.get(), errors);
+ GOOGLE_CHECK(dest);
+ dest->assign(unescaped.get(), len);
+ return len;
+}
+
+string UnescapeCEscapeString(const string& src) {
+ scoped_array<char> unescaped(new char[src.size() + 1]);
+ int len = UnescapeCEscapeSequences(src.c_str(), unescaped.get(), NULL);
+ return string(unescaped.get(), len);
+}
+
+// ----------------------------------------------------------------------
+// CEscapeString()
+// CHexEscapeString()
+// Copies 'src' to 'dest', escaping dangerous characters using
+// C-style escape sequences. This is very useful for preparing query
+// flags. 'src' and 'dest' should not overlap. The 'Hex' version uses
+// hexadecimal rather than octal sequences.
+// Returns the number of bytes written to 'dest' (not including the \0)
+// or -1 if there was insufficient space.
+//
+// Currently only \n, \r, \t, ", ', \ and !isprint() chars are escaped.
+// ----------------------------------------------------------------------
+int CEscapeInternal(const char* src, int src_len, char* dest,
+ int dest_len, bool use_hex, bool utf8_safe) {
+ const char* src_end = src + src_len;
+ int used = 0;
+ bool last_hex_escape = false; // true if last output char was \xNN
+
+ for (; src < src_end; src++) {
+ if (dest_len - used < 2) // Need space for two letter escape
+ return -1;
+
+ bool is_hex_escape = false;
+ switch (*src) {
+ case '\n': dest[used++] = '\\'; dest[used++] = 'n'; break;
+ case '\r': dest[used++] = '\\'; dest[used++] = 'r'; break;
+ case '\t': dest[used++] = '\\'; dest[used++] = 't'; break;
+ case '\"': dest[used++] = '\\'; dest[used++] = '\"'; break;
+ case '\'': dest[used++] = '\\'; dest[used++] = '\''; break;
+ case '\\': dest[used++] = '\\'; dest[used++] = '\\'; break;
+ default:
+ // Note that if we emit \xNN and the src character after that is a hex
+ // digit then that digit must be escaped too to prevent it being
+ // interpreted as part of the character code by C.
+ if ((!utf8_safe || static_cast<uint8>(*src) < 0x80) &&
+ (!isprint(*src) ||
+ (last_hex_escape && isxdigit(*src)))) {
+ if (dest_len - used < 4) // need space for 4 letter escape
+ return -1;
+ sprintf(dest + used, (use_hex ? "\\x%02x" : "\\%03o"),
+ static_cast<uint8>(*src));
+ is_hex_escape = use_hex;
+ used += 4;
+ } else {
+ dest[used++] = *src; break;
+ }
+ }
+ last_hex_escape = is_hex_escape;
+ }
+
+ if (dest_len - used < 1) // make sure that there is room for \0
+ return -1;
+
+ dest[used] = '\0'; // doesn't count towards return value though
+ return used;
+}
+
+int CEscapeString(const char* src, int src_len, char* dest, int dest_len) {
+ return CEscapeInternal(src, src_len, dest, dest_len, false, false);
+}
+
+// ----------------------------------------------------------------------
+// CEscape()
+// CHexEscape()
+// Copies 'src' to result, escaping dangerous characters using
+// C-style escape sequences. This is very useful for preparing query
+// flags. 'src' and 'dest' should not overlap. The 'Hex' version
+// hexadecimal rather than octal sequences.
+//
+// Currently only \n, \r, \t, ", ', \ and !isprint() chars are escaped.
+// ----------------------------------------------------------------------
+string CEscape(const string& src) {
+ const int dest_length = src.size() * 4 + 1; // Maximum possible expansion
+ scoped_array<char> dest(new char[dest_length]);
+ const int len = CEscapeInternal(src.data(), src.size(),
+ dest.get(), dest_length, false, false);
+ GOOGLE_DCHECK_GE(len, 0);
+ return string(dest.get(), len);
+}
+
+namespace strings {
+
+string Utf8SafeCEscape(const string& src) {
+ const int dest_length = src.size() * 4 + 1; // Maximum possible expansion
+ scoped_array<char> dest(new char[dest_length]);
+ const int len = CEscapeInternal(src.data(), src.size(),
+ dest.get(), dest_length, false, true);
+ GOOGLE_DCHECK_GE(len, 0);
+ return string(dest.get(), len);
+}
+
+string CHexEscape(const string& src) {
+ const int dest_length = src.size() * 4 + 1; // Maximum possible expansion
+ scoped_array<char> dest(new char[dest_length]);
+ const int len = CEscapeInternal(src.data(), src.size(),
+ dest.get(), dest_length, true, false);
+ GOOGLE_DCHECK_GE(len, 0);
+ return string(dest.get(), len);
+}
+
+} // namespace strings
+
+// ----------------------------------------------------------------------
+// strto32_adaptor()
+// strtou32_adaptor()
+// Implementation of strto[u]l replacements that have identical
+// overflow and underflow characteristics for both ILP-32 and LP-64
+// platforms, including errno preservation in error-free calls.
+// ----------------------------------------------------------------------
+
+int32 strto32_adaptor(const char *nptr, char **endptr, int base) {
+ const int saved_errno = errno;
+ errno = 0;
+ const long result = strtol(nptr, endptr, base);
+ if (errno == ERANGE && result == LONG_MIN) {
+ return kint32min;
+ } else if (errno == ERANGE && result == LONG_MAX) {
+ return kint32max;
+ } else if (errno == 0 && result < kint32min) {
+ errno = ERANGE;
+ return kint32min;
+ } else if (errno == 0 && result > kint32max) {
+ errno = ERANGE;
+ return kint32max;
+ }
+ if (errno == 0)
+ errno = saved_errno;
+ return static_cast<int32>(result);
+}
+
+uint32 strtou32_adaptor(const char *nptr, char **endptr, int base) {
+ const int saved_errno = errno;
+ errno = 0;
+ const unsigned long result = strtoul(nptr, endptr, base);
+ if (errno == ERANGE && result == ULONG_MAX) {
+ return kuint32max;
+ } else if (errno == 0 && result > kuint32max) {
+ errno = ERANGE;
+ return kuint32max;
+ }
+ if (errno == 0)
+ errno = saved_errno;
+ return static_cast<uint32>(result);
+}
+
+inline bool safe_parse_sign(string* text /*inout*/,
+ bool* negative_ptr /*output*/) {
+ const char* start = text->data();
+ const char* end = start + text->size();
+
+ // Consume whitespace.
+ while (start < end && (start[0] == ' ')) {
+ ++start;
+ }
+ while (start < end && (end[-1] == ' ')) {
+ --end;
+ }
+ if (start >= end) {
+ return false;
+ }
+
+ // Consume sign.
+ *negative_ptr = (start[0] == '-');
+ if (*negative_ptr || start[0] == '+') {
+ ++start;
+ if (start >= end) {
+ return false;
+ }
+ }
+ *text = text->substr(start - text->data(), end - start);
+ return true;
+}
+
+inline bool safe_parse_positive_int(
+ string text, int32* value_p) {
+ int base = 10;
+ int32 value = 0;
+ const int32 vmax = std::numeric_limits<int32>::max();
+ assert(vmax > 0);
+ assert(vmax >= base);
+ const int32 vmax_over_base = vmax / base;
+ const char* start = text.data();
+ const char* end = start + text.size();
+ // loop over digits
+ for (; start < end; ++start) {
+ unsigned char c = static_cast<unsigned char>(start[0]);
+ int digit = c - '0';
+ if (digit >= base || digit < 0) {
+ *value_p = value;
+ return false;
+ }
+ if (value > vmax_over_base) {
+ *value_p = vmax;
+ return false;
+ }
+ value *= base;
+ if (value > vmax - digit) {
+ *value_p = vmax;
+ return false;
+ }
+ value += digit;
+ }
+ *value_p = value;
+ return true;
+}
+
+inline bool safe_parse_negative_int(
+ string text, int32* value_p) {
+ int base = 10;
+ int32 value = 0;
+ const int32 vmin = std::numeric_limits<int32>::min();
+ assert(vmin < 0);
+ assert(vmin <= 0 - base);
+ int32 vmin_over_base = vmin / base;
+ // 2003 c++ standard [expr.mul]
+ // "... the sign of the remainder is implementation-defined."
+ // Although (vmin/base)*base + vmin%base is always vmin.
+ // 2011 c++ standard tightens the spec but we cannot rely on it.
+ if (vmin % base > 0) {
+ vmin_over_base += 1;
+ }
+ const char* start = text.data();
+ const char* end = start + text.size();
+ // loop over digits
+ for (; start < end; ++start) {
+ unsigned char c = static_cast<unsigned char>(start[0]);
+ int digit = c - '0';
+ if (digit >= base || digit < 0) {
+ *value_p = value;
+ return false;
+ }
+ if (value < vmin_over_base) {
+ *value_p = vmin;
+ return false;
+ }
+ value *= base;
+ if (value < vmin + digit) {
+ *value_p = vmin;
+ return false;
+ }
+ value -= digit;
+ }
+ *value_p = value;
+ return true;
+}
+
+bool safe_int(string text, int32* value_p) {
+ *value_p = 0;
+ bool negative;
+ if (!safe_parse_sign(&text, &negative)) {
+ return false;
+ }
+ if (!negative) {
+ return safe_parse_positive_int(text, value_p);
+ } else {
+ return safe_parse_negative_int(text, value_p);
+ }
+}
+
+// ----------------------------------------------------------------------
+// FastIntToBuffer()
+// FastInt64ToBuffer()
+// FastHexToBuffer()
+// FastHex64ToBuffer()
+// FastHex32ToBuffer()
+// ----------------------------------------------------------------------
+
+// Offset into buffer where FastInt64ToBuffer places the end of string
+// null character. Also used by FastInt64ToBufferLeft.
+static const int kFastInt64ToBufferOffset = 21;
+
+char *FastInt64ToBuffer(int64 i, char* buffer) {
+ // We could collapse the positive and negative sections, but that
+ // would be slightly slower for positive numbers...
+ // 22 bytes is enough to store -2**64, -18446744073709551616.
+ char* p = buffer + kFastInt64ToBufferOffset;
+ *p-- = '\0';
+ if (i >= 0) {
+ do {
+ *p-- = '0' + i % 10;
+ i /= 10;
+ } while (i > 0);
+ return p + 1;
+ } else {
+ // On different platforms, % and / have different behaviors for
+ // negative numbers, so we need to jump through hoops to make sure
+ // we don't divide negative numbers.
+ if (i > -10) {
+ i = -i;
+ *p-- = '0' + i;
+ *p = '-';
+ return p;
+ } else {
+ // Make sure we aren't at MIN_INT, in which case we can't say i = -i
+ i = i + 10;
+ i = -i;
+ *p-- = '0' + i % 10;
+ // Undo what we did a moment ago
+ i = i / 10 + 1;
+ do {
+ *p-- = '0' + i % 10;
+ i /= 10;
+ } while (i > 0);
+ *p = '-';
+ return p;
+ }
+ }
+}
+
+// Offset into buffer where FastInt32ToBuffer places the end of string
+// null character. Also used by FastInt32ToBufferLeft
+static const int kFastInt32ToBufferOffset = 11;
+
+// Yes, this is a duplicate of FastInt64ToBuffer. But, we need this for the
+// compiler to generate 32 bit arithmetic instructions. It's much faster, at
+// least with 32 bit binaries.
+char *FastInt32ToBuffer(int32 i, char* buffer) {
+ // We could collapse the positive and negative sections, but that
+ // would be slightly slower for positive numbers...
+ // 12 bytes is enough to store -2**32, -4294967296.
+ char* p = buffer + kFastInt32ToBufferOffset;
+ *p-- = '\0';
+ if (i >= 0) {
+ do {
+ *p-- = '0' + i % 10;
+ i /= 10;
+ } while (i > 0);
+ return p + 1;
+ } else {
+ // On different platforms, % and / have different behaviors for
+ // negative numbers, so we need to jump through hoops to make sure
+ // we don't divide negative numbers.
+ if (i > -10) {
+ i = -i;
+ *p-- = '0' + i;
+ *p = '-';
+ return p;
+ } else {
+ // Make sure we aren't at MIN_INT, in which case we can't say i = -i
+ i = i + 10;
+ i = -i;
+ *p-- = '0' + i % 10;
+ // Undo what we did a moment ago
+ i = i / 10 + 1;
+ do {
+ *p-- = '0' + i % 10;
+ i /= 10;
+ } while (i > 0);
+ *p = '-';
+ return p;
+ }
+ }
+}
+
+char *FastHexToBuffer(int i, char* buffer) {
+ GOOGLE_CHECK(i >= 0) << "FastHexToBuffer() wants non-negative integers, not " << i;
+
+ static const char *hexdigits = "0123456789abcdef";
+ char *p = buffer + 21;
+ *p-- = '\0';
+ do {
+ *p-- = hexdigits[i & 15]; // mod by 16
+ i >>= 4; // divide by 16
+ } while (i > 0);
+ return p + 1;
+}
+
+char *InternalFastHexToBuffer(uint64 value, char* buffer, int num_byte) {
+ static const char *hexdigits = "0123456789abcdef";
+ buffer[num_byte] = '\0';
+ for (int i = num_byte - 1; i >= 0; i--) {
+#ifdef _M_X64
+ // MSVC x64 platform has a bug optimizing the uint32(value) in the #else
+ // block. Given that the uint32 cast was to improve performance on 32-bit
+ // platforms, we use 64-bit '&' directly.
+ buffer[i] = hexdigits[value & 0xf];
+#else
+ buffer[i] = hexdigits[uint32(value) & 0xf];
+#endif
+ value >>= 4;
+ }
+ return buffer;
+}
+
+char *FastHex64ToBuffer(uint64 value, char* buffer) {
+ return InternalFastHexToBuffer(value, buffer, 16);
+}
+
+char *FastHex32ToBuffer(uint32 value, char* buffer) {
+ return InternalFastHexToBuffer(value, buffer, 8);
+}
+
+static inline char* PlaceNum(char* p, int num, char prev_sep) {
+ *p-- = '0' + num % 10;
+ *p-- = '0' + num / 10;
+ *p-- = prev_sep;
+ return p;
+}
+
+// ----------------------------------------------------------------------
+// FastInt32ToBufferLeft()
+// FastUInt32ToBufferLeft()
+// FastInt64ToBufferLeft()
+// FastUInt64ToBufferLeft()
+//
+// Like the Fast*ToBuffer() functions above, these are intended for speed.
+// Unlike the Fast*ToBuffer() functions, however, these functions write
+// their output to the beginning of the buffer (hence the name, as the
+// output is left-aligned). The caller is responsible for ensuring that
+// the buffer has enough space to hold the output.
+//
+// Returns a pointer to the end of the string (i.e. the null character
+// terminating the string).
+// ----------------------------------------------------------------------
+
+static const char two_ASCII_digits[100][2] = {
+ {'0','0'}, {'0','1'}, {'0','2'}, {'0','3'}, {'0','4'},
+ {'0','5'}, {'0','6'}, {'0','7'}, {'0','8'}, {'0','9'},
+ {'1','0'}, {'1','1'}, {'1','2'}, {'1','3'}, {'1','4'},
+ {'1','5'}, {'1','6'}, {'1','7'}, {'1','8'}, {'1','9'},
+ {'2','0'}, {'2','1'}, {'2','2'}, {'2','3'}, {'2','4'},
+ {'2','5'}, {'2','6'}, {'2','7'}, {'2','8'}, {'2','9'},
+ {'3','0'}, {'3','1'}, {'3','2'}, {'3','3'}, {'3','4'},
+ {'3','5'}, {'3','6'}, {'3','7'}, {'3','8'}, {'3','9'},
+ {'4','0'}, {'4','1'}, {'4','2'}, {'4','3'}, {'4','4'},
+ {'4','5'}, {'4','6'}, {'4','7'}, {'4','8'}, {'4','9'},
+ {'5','0'}, {'5','1'}, {'5','2'}, {'5','3'}, {'5','4'},
+ {'5','5'}, {'5','6'}, {'5','7'}, {'5','8'}, {'5','9'},
+ {'6','0'}, {'6','1'}, {'6','2'}, {'6','3'}, {'6','4'},
+ {'6','5'}, {'6','6'}, {'6','7'}, {'6','8'}, {'6','9'},
+ {'7','0'}, {'7','1'}, {'7','2'}, {'7','3'}, {'7','4'},
+ {'7','5'}, {'7','6'}, {'7','7'}, {'7','8'}, {'7','9'},
+ {'8','0'}, {'8','1'}, {'8','2'}, {'8','3'}, {'8','4'},
+ {'8','5'}, {'8','6'}, {'8','7'}, {'8','8'}, {'8','9'},
+ {'9','0'}, {'9','1'}, {'9','2'}, {'9','3'}, {'9','4'},
+ {'9','5'}, {'9','6'}, {'9','7'}, {'9','8'}, {'9','9'}
+};
+
+char* FastUInt32ToBufferLeft(uint32 u, char* buffer) {
+ int digits;
+ const char *ASCII_digits = NULL;
+ // The idea of this implementation is to trim the number of divides to as few
+ // as possible by using multiplication and subtraction rather than mod (%),
+ // and by outputting two digits at a time rather than one.
+ // The huge-number case is first, in the hopes that the compiler will output
+ // that case in one branch-free block of code, and only output conditional
+ // branches into it from below.
+ if (u >= 1000000000) { // >= 1,000,000,000
+ digits = u / 100000000; // 100,000,000
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+sublt100_000_000:
+ u -= digits * 100000000; // 100,000,000
+lt100_000_000:
+ digits = u / 1000000; // 1,000,000
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+sublt1_000_000:
+ u -= digits * 1000000; // 1,000,000
+lt1_000_000:
+ digits = u / 10000; // 10,000
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+sublt10_000:
+ u -= digits * 10000; // 10,000
+lt10_000:
+ digits = u / 100;
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+sublt100:
+ u -= digits * 100;
+lt100:
+ digits = u;
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+done:
+ *buffer = 0;
+ return buffer;
+ }
+
+ if (u < 100) {
+ digits = u;
+ if (u >= 10) goto lt100;
+ *buffer++ = '0' + digits;
+ goto done;
+ }
+ if (u < 10000) { // 10,000
+ if (u >= 1000) goto lt10_000;
+ digits = u / 100;
+ *buffer++ = '0' + digits;
+ goto sublt100;
+ }
+ if (u < 1000000) { // 1,000,000
+ if (u >= 100000) goto lt1_000_000;
+ digits = u / 10000; // 10,000
+ *buffer++ = '0' + digits;
+ goto sublt10_000;
+ }
+ if (u < 100000000) { // 100,000,000
+ if (u >= 10000000) goto lt100_000_000;
+ digits = u / 1000000; // 1,000,000
+ *buffer++ = '0' + digits;
+ goto sublt1_000_000;
+ }
+ // we already know that u < 1,000,000,000
+ digits = u / 100000000; // 100,000,000
+ *buffer++ = '0' + digits;
+ goto sublt100_000_000;
+}
+
+char* FastInt32ToBufferLeft(int32 i, char* buffer) {
+ uint32 u = i;
+ if (i < 0) {
+ *buffer++ = '-';
+ u = -i;
+ }
+ return FastUInt32ToBufferLeft(u, buffer);
+}
+
+char* FastUInt64ToBufferLeft(uint64 u64, char* buffer) {
+ int digits;
+ const char *ASCII_digits = NULL;
+
+ uint32 u = static_cast<uint32>(u64);
+ if (u == u64) return FastUInt32ToBufferLeft(u, buffer);
+
+ uint64 top_11_digits = u64 / 1000000000;
+ buffer = FastUInt64ToBufferLeft(top_11_digits, buffer);
+ u = u64 - (top_11_digits * 1000000000);
+
+ digits = u / 10000000; // 10,000,000
+ GOOGLE_DCHECK_LT(digits, 100);
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+ u -= digits * 10000000; // 10,000,000
+ digits = u / 100000; // 100,000
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+ u -= digits * 100000; // 100,000
+ digits = u / 1000; // 1,000
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+ u -= digits * 1000; // 1,000
+ digits = u / 10;
+ ASCII_digits = two_ASCII_digits[digits];
+ buffer[0] = ASCII_digits[0];
+ buffer[1] = ASCII_digits[1];
+ buffer += 2;
+ u -= digits * 10;
+ digits = u;
+ *buffer++ = '0' + digits;
+ *buffer = 0;
+ return buffer;
+}
+
+char* FastInt64ToBufferLeft(int64 i, char* buffer) {
+ uint64 u = i;
+ if (i < 0) {
+ *buffer++ = '-';
+ u = -i;
+ }
+ return FastUInt64ToBufferLeft(u, buffer);
+}
+
+// ----------------------------------------------------------------------
+// SimpleItoa()
+// Description: converts an integer to a string.
+//
+// Return value: string
+// ----------------------------------------------------------------------
+
+string SimpleItoa(int i) {
+ char buffer[kFastToBufferSize];
+ return (sizeof(i) == 4) ?
+ FastInt32ToBuffer(i, buffer) :
+ FastInt64ToBuffer(i, buffer);
+}
+
+string SimpleItoa(unsigned int i) {
+ char buffer[kFastToBufferSize];
+ return string(buffer, (sizeof(i) == 4) ?
+ FastUInt32ToBufferLeft(i, buffer) :
+ FastUInt64ToBufferLeft(i, buffer));
+}
+
+string SimpleItoa(long i) {
+ char buffer[kFastToBufferSize];
+ return (sizeof(i) == 4) ?
+ FastInt32ToBuffer(i, buffer) :
+ FastInt64ToBuffer(i, buffer);
+}
+
+string SimpleItoa(unsigned long i) {
+ char buffer[kFastToBufferSize];
+ return string(buffer, (sizeof(i) == 4) ?
+ FastUInt32ToBufferLeft(i, buffer) :
+ FastUInt64ToBufferLeft(i, buffer));
+}
+
+string SimpleItoa(long long i) {
+ char buffer[kFastToBufferSize];
+ return (sizeof(i) == 4) ?
+ FastInt32ToBuffer(i, buffer) :
+ FastInt64ToBuffer(i, buffer);
+}
+
+string SimpleItoa(unsigned long long i) {
+ char buffer[kFastToBufferSize];
+ return string(buffer, (sizeof(i) == 4) ?
+ FastUInt32ToBufferLeft(i, buffer) :
+ FastUInt64ToBufferLeft(i, buffer));
+}
+
+// ----------------------------------------------------------------------
+// SimpleDtoa()
+// SimpleFtoa()
+// DoubleToBuffer()
+// FloatToBuffer()
+// We want to print the value without losing precision, but we also do
+// not want to print more digits than necessary. This turns out to be
+// trickier than it sounds. Numbers like 0.2 cannot be represented
+// exactly in binary. If we print 0.2 with a very large precision,
+// e.g. "%.50g", we get "0.2000000000000000111022302462515654042363167".
+// On the other hand, if we set the precision too low, we lose
+// significant digits when printing numbers that actually need them.
+// It turns out there is no precision value that does the right thing
+// for all numbers.
+//
+// Our strategy is to first try printing with a precision that is never
+// over-precise, then parse the result with strtod() to see if it
+// matches. If not, we print again with a precision that will always
+// give a precise result, but may use more digits than necessary.
+//
+// An arguably better strategy would be to use the algorithm described
+// in "How to Print Floating-Point Numbers Accurately" by Steele &
+// White, e.g. as implemented by David M. Gay's dtoa(). It turns out,
+// however, that the following implementation is about as fast as
+// DMG's code. Furthermore, DMG's code locks mutexes, which means it
+// will not scale well on multi-core machines. DMG's code is slightly
+// more accurate (in that it will never use more digits than
+// necessary), but this is probably irrelevant for most users.
+//
+// Rob Pike and Ken Thompson also have an implementation of dtoa() in
+// third_party/fmt/fltfmt.cc. Their implementation is similar to this
+// one in that it makes guesses and then uses strtod() to check them.
+// Their implementation is faster because they use their own code to
+// generate the digits in the first place rather than use snprintf(),
+// thus avoiding format string parsing overhead. However, this makes
+// it considerably more complicated than the following implementation,
+// and it is embedded in a larger library. If speed turns out to be
+// an issue, we could re-implement this in terms of their
+// implementation.
+// ----------------------------------------------------------------------
+
+string SimpleDtoa(double value) {
+ char buffer[kDoubleToBufferSize];
+ return DoubleToBuffer(value, buffer);
+}
+
+string SimpleFtoa(float value) {
+ char buffer[kFloatToBufferSize];
+ return FloatToBuffer(value, buffer);
+}
+
+static inline bool IsValidFloatChar(char c) {
+ return ('0' <= c && c <= '9') ||
+ c == 'e' || c == 'E' ||
+ c == '+' || c == '-';
+}
+
+void DelocalizeRadix(char* buffer) {
+ // Fast check: if the buffer has a normal decimal point, assume no
+ // translation is needed.
+ if (strchr(buffer, '.') != NULL) return;
+
+ // Find the first unknown character.
+ while (IsValidFloatChar(*buffer)) ++buffer;
+
+ if (*buffer == '\0') {
+ // No radix character found.
+ return;
+ }
+
+ // We are now pointing at the locale-specific radix character. Replace it
+ // with '.'.
+ *buffer = '.';
+ ++buffer;
+
+ if (!IsValidFloatChar(*buffer) && *buffer != '\0') {
+ // It appears the radix was a multi-byte character. We need to remove the
+ // extra bytes.
+ char* target = buffer;
+ do { ++buffer; } while (!IsValidFloatChar(*buffer) && *buffer != '\0');
+ memmove(target, buffer, strlen(buffer) + 1);
+ }
+}
+
+char* DoubleToBuffer(double value, char* buffer) {
+ // DBL_DIG is 15 for IEEE-754 doubles, which are used on almost all
+ // platforms these days. Just in case some system exists where DBL_DIG
+ // is significantly larger -- and risks overflowing our buffer -- we have
+ // this assert.
+ GOOGLE_COMPILE_ASSERT(DBL_DIG < 20, DBL_DIG_is_too_big);
+
+ if (value == numeric_limits<double>::infinity()) {
+ strcpy(buffer, "inf");
+ return buffer;
+ } else if (value == -numeric_limits<double>::infinity()) {
+ strcpy(buffer, "-inf");
+ return buffer;
+ } else if (IsNaN(value)) {
+ strcpy(buffer, "nan");
+ return buffer;
+ }
+
+ int snprintf_result =
+ snprintf(buffer, kDoubleToBufferSize, "%.*g", DBL_DIG, value);
+
+ // The snprintf should never overflow because the buffer is significantly
+ // larger than the precision we asked for.
+ GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kDoubleToBufferSize);
+
+ // We need to make parsed_value volatile in order to force the compiler to
+ // write it out to the stack. Otherwise, it may keep the value in a
+ // register, and if it does that, it may keep it as a long double instead
+ // of a double. This long double may have extra bits that make it compare
+ // unequal to "value" even though it would be exactly equal if it were
+ // truncated to a double.
+ volatile double parsed_value = strtod(buffer, NULL);
+ if (parsed_value != value) {
+ int snprintf_result =
+ snprintf(buffer, kDoubleToBufferSize, "%.*g", DBL_DIG+2, value);
+
+ // Should never overflow; see above.
+ GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kDoubleToBufferSize);
+ }
+
+ DelocalizeRadix(buffer);
+ return buffer;
+}
+
+bool safe_strtof(const char* str, float* value) {
+ char* endptr;
+ errno = 0; // errno only gets set on errors
+#if defined(_WIN32) || defined (__hpux) // has no strtof()
+ *value = strtod(str, &endptr);
+#else
+ *value = strtof(str, &endptr);
+#endif
+ return *str != 0 && *endptr == 0 && errno == 0;
+}
+
+char* FloatToBuffer(float value, char* buffer) {
+ // FLT_DIG is 6 for IEEE-754 floats, which are used on almost all
+ // platforms these days. Just in case some system exists where FLT_DIG
+ // is significantly larger -- and risks overflowing our buffer -- we have
+ // this assert.
+ GOOGLE_COMPILE_ASSERT(FLT_DIG < 10, FLT_DIG_is_too_big);
+
+ if (value == numeric_limits<double>::infinity()) {
+ strcpy(buffer, "inf");
+ return buffer;
+ } else if (value == -numeric_limits<double>::infinity()) {
+ strcpy(buffer, "-inf");
+ return buffer;
+ } else if (IsNaN(value)) {
+ strcpy(buffer, "nan");
+ return buffer;
+ }
+
+ int snprintf_result =
+ snprintf(buffer, kFloatToBufferSize, "%.*g", FLT_DIG, value);
+
+ // The snprintf should never overflow because the buffer is significantly
+ // larger than the precision we asked for.
+ GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kFloatToBufferSize);
+
+ float parsed_value;
+ if (!safe_strtof(buffer, &parsed_value) || parsed_value != value) {
+ int snprintf_result =
+ snprintf(buffer, kFloatToBufferSize, "%.*g", FLT_DIG+2, value);
+
+ // Should never overflow; see above.
+ GOOGLE_DCHECK(snprintf_result > 0 && snprintf_result < kFloatToBufferSize);
+ }
+
+ DelocalizeRadix(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 protobuf
+} // namespace google
diff --git a/contrib/protoc-bnet/google/protobuf/stubs/strutil.h b/contrib/protoc-bnet/google/protobuf/stubs/strutil.h
new file mode 100644
index 00000000000..4178ac9ff63
--- /dev/null
+++ b/contrib/protoc-bnet/google/protobuf/stubs/strutil.h
@@ -0,0 +1,562 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// from google3/strings/strutil.h
+
+#ifndef GOOGLE_PROTOBUF_STUBS_STRUTIL_H__
+#define GOOGLE_PROTOBUF_STUBS_STRUTIL_H__
+
+#include <stdlib.h>
+#include <vector>
+#include <google/protobuf/stubs/common.h>
+
+namespace google {
+namespace protobuf {
+
+#ifdef _MSC_VER
+#define strtoll _strtoi64
+#define strtoull _strtoui64
+#elif defined(__DECCXX) && defined(__osf__)
+// HP C++ on Tru64 does not have strtoll, but strtol is already 64-bit.
+#define strtoll strtol
+#define strtoull strtoul
+#endif
+
+// ----------------------------------------------------------------------
+// ascii_isalnum()
+// Check if an ASCII character is alphanumeric. We can't use ctype's
+// isalnum() because it is affected by locale. This function is applied
+// to identifiers in the protocol buffer language, not to natural-language
+// strings, so locale should not be taken into account.
+// ascii_isdigit()
+// Like above, but only accepts digits.
+// ----------------------------------------------------------------------
+
+inline bool ascii_isalnum(char c) {
+ return ('a' <= c && c <= 'z') ||
+ ('A' <= c && c <= 'Z') ||
+ ('0' <= c && c <= '9');
+}
+
+inline bool ascii_isdigit(char c) {
+ return ('0' <= c && c <= '9');
+}
+
+// ----------------------------------------------------------------------
+// HasPrefixString()
+// Check if a string begins with a given prefix.
+// StripPrefixString()
+// Given a string and a putative prefix, returns the string minus the
+// prefix string if the prefix matches, otherwise the original
+// string.
+// ----------------------------------------------------------------------
+inline bool HasPrefixString(const string& str,
+ const string& prefix) {
+ return str.size() >= prefix.size() &&
+ str.compare(0, prefix.size(), prefix) == 0;
+}
+
+inline string StripPrefixString(const string& str, const string& prefix) {
+ if (HasPrefixString(str, prefix)) {
+ return str.substr(prefix.size());
+ } else {
+ return str;
+ }
+}
+
+// ----------------------------------------------------------------------
+// HasSuffixString()
+// Return true if str ends in suffix.
+// StripSuffixString()
+// Given a string and a putative suffix, returns the string minus the
+// suffix string if the suffix matches, otherwise the original
+// string.
+// ----------------------------------------------------------------------
+inline bool HasSuffixString(const string& str,
+ const string& suffix) {
+ return str.size() >= suffix.size() &&
+ str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
+}
+
+inline string StripSuffixString(const string& str, const string& suffix) {
+ if (HasSuffixString(str, suffix)) {
+ return str.substr(0, str.size() - suffix.size());
+ } else {
+ return str;
+ }
+}
+
+// ----------------------------------------------------------------------
+// StripString
+// Replaces any occurrence of the character 'remove' (or the characters
+// in 'remove') with the character 'replacewith'.
+// Good for keeping html characters or protocol characters (\t) out
+// of places where they might cause a problem.
+// ----------------------------------------------------------------------
+LIBPROTOBUF_EXPORT void StripString(string* s, const char* remove,
+ char replacewith);
+
+// ----------------------------------------------------------------------
+// LowerString()
+// UpperString()
+// ToUpper()
+// Convert the characters in "s" to lowercase or uppercase. ASCII-only:
+// these functions intentionally ignore locale because they are applied to
+// identifiers used in the Protocol Buffer language, not to natural-language
+// strings.
+// ----------------------------------------------------------------------
+
+inline void LowerString(string * s) {
+ string::iterator end = s->end();
+ for (string::iterator i = s->begin(); i != end; ++i) {
+ // tolower() changes based on locale. We don't want this!
+ if ('A' <= *i && *i <= 'Z') *i += 'a' - 'A';
+ }
+}
+
+inline void UpperString(string * s) {
+ string::iterator end = s->end();
+ for (string::iterator i = s->begin(); i != end; ++i) {
+ // toupper() changes based on locale. We don't want this!
+ if ('a' <= *i && *i <= 'z') *i += 'A' - 'a';
+ }
+}
+
+inline string ToUpper(const string& s) {
+ string out = s;
+ UpperString(&out);
+ return out;
+}
+
+// ----------------------------------------------------------------------
+// StringReplace()
+// Give me a string and two patterns "old" and "new", and I replace
+// the first instance of "old" in the string with "new", if it
+// exists. RETURN a new string, regardless of whether the replacement
+// happened or not.
+// ----------------------------------------------------------------------
+
+LIBPROTOBUF_EXPORT string StringReplace(const string& s, const string& oldsub,
+ const string& newsub, bool replace_all);
+
+// ----------------------------------------------------------------------
+// SplitStringUsing()
+// Split a string using a character delimiter. Append the components
+// to 'result'. If there are consecutive delimiters, this function skips
+// over all of them.
+// ----------------------------------------------------------------------
+LIBPROTOBUF_EXPORT void SplitStringUsing(const string& full, const char* delim,
+ vector<string>* res);
+
+// Split a string using one or more byte delimiters, presented
+// as a nul-terminated c string. Append the components to 'result'.
+// If there are consecutive delimiters, this function will return
+// corresponding empty strings. If you want to drop the empty
+// strings, try SplitStringUsing().
+//
+// If "full" is the empty string, yields an empty string as the only value.
+// ----------------------------------------------------------------------
+LIBPROTOBUF_EXPORT void SplitStringAllowEmpty(const string& full,
+ const char* delim,
+ vector<string>* result);
+
+// ----------------------------------------------------------------------
+// Split()
+// Split a string using a character delimiter.
+// ----------------------------------------------------------------------
+inline vector<string> Split(
+ const string& full, const char* delim, bool skip_empty = true) {
+ vector<string> result;
+ if (skip_empty) {
+ SplitStringUsing(full, delim, &result);
+ } else {
+ SplitStringAllowEmpty(full, delim, &result);
+ }
+ return result;
+}
+
+// ----------------------------------------------------------------------
+// JoinStrings()
+// These methods concatenate a vector of strings into a C++ string, using
+// the C-string "delim" as a separator between components. There are two
+// flavors of the function, one flavor returns the concatenated string,
+// another takes a pointer to the target string. In the latter case the
+// target string is cleared and overwritten.
+// ----------------------------------------------------------------------
+LIBPROTOBUF_EXPORT void JoinStrings(const vector<string>& components,
+ const char* delim, string* result);
+
+inline string JoinStrings(const vector<string>& components,
+ const char* delim) {
+ string result;
+ JoinStrings(components, delim, &result);
+ return result;
+}
+
+// ----------------------------------------------------------------------
+// UnescapeCEscapeSequences()
+// Copies "source" to "dest", rewriting C-style escape sequences
+// -- '\n', '\r', '\\', '\ooo', etc -- to their ASCII
+// equivalents. "dest" must be sufficiently large to hold all
+// the characters in the rewritten string (i.e. at least as large
+// as strlen(source) + 1 should be safe, since the replacements
+// are always shorter than the original escaped sequences). It's
+// safe for source and dest to be the same. RETURNS the length
+// of dest.
+//
+// It allows hex sequences \xhh, or generally \xhhhhh with an
+// arbitrary number of hex digits, but all of them together must
+// specify a value of a single byte (e.g. \x0045 is equivalent
+// to \x45, and \x1234 is erroneous).
+//
+// It also allows escape sequences of the form \uhhhh (exactly four
+// hex digits, upper or lower case) or \Uhhhhhhhh (exactly eight
+// hex digits, upper or lower case) to specify a Unicode code
+// point. The dest array will contain the UTF8-encoded version of
+// that code-point (e.g., if source contains \u2019, then dest will
+// contain the three bytes 0xE2, 0x80, and 0x99).
+//
+// Errors: In the first form of the call, errors are reported with
+// LOG(ERROR). The same is true for the second form of the call if
+// the pointer to the string vector is NULL; otherwise, error
+// messages are stored in the vector. In either case, the effect on
+// the dest array is not defined, but rest of the source will be
+// processed.
+// ----------------------------------------------------------------------
+
+LIBPROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest);
+LIBPROTOBUF_EXPORT int UnescapeCEscapeSequences(const char* source, char* dest,
+ vector<string> *errors);
+
+// ----------------------------------------------------------------------
+// UnescapeCEscapeString()
+// This does the same thing as UnescapeCEscapeSequences, but creates
+// a new string. The caller does not need to worry about allocating
+// a dest buffer. This should be used for non performance critical
+// tasks such as printing debug messages. It is safe for src and dest
+// to be the same.
+//
+// The second call stores its errors in a supplied string vector.
+// If the string vector pointer is NULL, it reports the errors with LOG().
+//
+// In the first and second calls, the length of dest is returned. In the
+// the third call, the new string is returned.
+// ----------------------------------------------------------------------
+
+LIBPROTOBUF_EXPORT int UnescapeCEscapeString(const string& src, string* dest);
+LIBPROTOBUF_EXPORT int UnescapeCEscapeString(const string& src, string* dest,
+ vector<string> *errors);
+LIBPROTOBUF_EXPORT string UnescapeCEscapeString(const string& src);
+
+// ----------------------------------------------------------------------
+// CEscapeString()
+// Copies 'src' to 'dest', escaping dangerous characters using
+// C-style escape sequences. This is very useful for preparing query
+// flags. 'src' and 'dest' should not overlap.
+// Returns the number of bytes written to 'dest' (not including the \0)
+// or -1 if there was insufficient space.
+//
+// Currently only \n, \r, \t, ", ', \ and !isprint() chars are escaped.
+// ----------------------------------------------------------------------
+LIBPROTOBUF_EXPORT int CEscapeString(const char* src, int src_len,
+ char* dest, int dest_len);
+
+// ----------------------------------------------------------------------
+// CEscape()
+// More convenient form of CEscapeString: returns result as a "string".
+// This version is slower than CEscapeString() because it does more
+// allocation. However, it is much more convenient to use in
+// non-speed-critical code like logging messages etc.
+// ----------------------------------------------------------------------
+LIBPROTOBUF_EXPORT string CEscape(const string& src);
+
+namespace strings {
+// Like CEscape() but does not escape bytes with the upper bit set.
+LIBPROTOBUF_EXPORT string Utf8SafeCEscape(const string& src);
+
+// Like CEscape() but uses hex (\x) escapes instead of octals.
+LIBPROTOBUF_EXPORT string CHexEscape(const string& src);
+} // namespace strings
+
+// ----------------------------------------------------------------------
+// strto32()
+// strtou32()
+// strto64()
+// strtou64()
+// Architecture-neutral plug compatible replacements for strtol() and
+// strtoul(). Long's have different lengths on ILP-32 and LP-64
+// platforms, so using these is safer, from the point of view of
+// overflow behavior, than using the standard libc functions.
+// ----------------------------------------------------------------------
+LIBPROTOBUF_EXPORT int32 strto32_adaptor(const char *nptr, char **endptr,
+ int base);
+LIBPROTOBUF_EXPORT uint32 strtou32_adaptor(const char *nptr, char **endptr,
+ int base);
+
+inline int32 strto32(const char *nptr, char **endptr, int base) {
+ if (sizeof(int32) == sizeof(long))
+ return strtol(nptr, endptr, base);
+ else
+ return strto32_adaptor(nptr, endptr, base);
+}
+
+inline uint32 strtou32(const char *nptr, char **endptr, int base) {
+ if (sizeof(uint32) == sizeof(unsigned long))
+ return strtoul(nptr, endptr, base);
+ else
+ return strtou32_adaptor(nptr, endptr, base);
+}
+
+// For now, long long is 64-bit on all the platforms we care about, so these
+// functions can simply pass the call to strto[u]ll.
+inline int64 strto64(const char *nptr, char **endptr, int base) {
+ GOOGLE_COMPILE_ASSERT(sizeof(int64) == sizeof(long long),
+ sizeof_int64_is_not_sizeof_long_long);
+ return strtoll(nptr, endptr, base);
+}
+
+inline uint64 strtou64(const char *nptr, char **endptr, int base) {
+ GOOGLE_COMPILE_ASSERT(sizeof(uint64) == sizeof(unsigned long long),
+ sizeof_uint64_is_not_sizeof_long_long);
+ return strtoull(nptr, endptr, base);
+}
+
+// ----------------------------------------------------------------------
+// safe_strto32()
+// ----------------------------------------------------------------------
+LIBPROTOBUF_EXPORT bool safe_int(string text, int32* value_p);
+
+inline bool safe_strto32(string text, int32* value) {
+ return safe_int(text, value);
+}
+
+// ----------------------------------------------------------------------
+// FastIntToBuffer()
+// FastHexToBuffer()
+// FastHex64ToBuffer()
+// FastHex32ToBuffer()
+// FastTimeToBuffer()
+// These are intended for speed. FastIntToBuffer() assumes the
+// integer is non-negative. FastHexToBuffer() puts output in
+// hex rather than decimal. FastTimeToBuffer() puts the output
+// into RFC822 format.
+//
+// FastHex64ToBuffer() puts a 64-bit unsigned value in hex-format,
+// padded to exactly 16 bytes (plus one byte for '\0')
+//
+// FastHex32ToBuffer() puts a 32-bit unsigned value in hex-format,
+// padded to exactly 8 bytes (plus one byte for '\0')
+//
+// All functions take the output buffer as an arg.
+// They all return a pointer to the beginning of the output,
+// which may not be the beginning of the input buffer.
+// ----------------------------------------------------------------------
+
+// Suggested buffer size for FastToBuffer functions. Also works with
+// DoubleToBuffer() and FloatToBuffer().
+static const int kFastToBufferSize = 32;
+
+LIBPROTOBUF_EXPORT char* FastInt32ToBuffer(int32 i, char* buffer);
+LIBPROTOBUF_EXPORT char* FastInt64ToBuffer(int64 i, char* buffer);
+char* FastUInt32ToBuffer(uint32 i, char* buffer); // inline below
+char* FastUInt64ToBuffer(uint64 i, char* buffer); // inline below
+LIBPROTOBUF_EXPORT char* FastHexToBuffer(int i, char* buffer);
+LIBPROTOBUF_EXPORT char* FastHex64ToBuffer(uint64 i, char* buffer);
+LIBPROTOBUF_EXPORT char* FastHex32ToBuffer(uint32 i, char* buffer);
+
+// at least 22 bytes long
+inline char* FastIntToBuffer(int i, char* buffer) {
+ return (sizeof(i) == 4 ?
+ FastInt32ToBuffer(i, buffer) : FastInt64ToBuffer(i, buffer));
+}
+inline char* FastUIntToBuffer(unsigned int i, char* buffer) {
+ return (sizeof(i) == 4 ?
+ FastUInt32ToBuffer(i, buffer) : FastUInt64ToBuffer(i, buffer));
+}
+inline char* FastLongToBuffer(long i, char* buffer) {
+ return (sizeof(i) == 4 ?
+ FastInt32ToBuffer(i, buffer) : FastInt64ToBuffer(i, buffer));
+}
+inline char* FastULongToBuffer(unsigned long i, char* buffer) {
+ return (sizeof(i) == 4 ?
+ FastUInt32ToBuffer(i, buffer) : FastUInt64ToBuffer(i, buffer));
+}
+
+// ----------------------------------------------------------------------
+// FastInt32ToBufferLeft()
+// FastUInt32ToBufferLeft()
+// FastInt64ToBufferLeft()
+// FastUInt64ToBufferLeft()
+//
+// Like the Fast*ToBuffer() functions above, these are intended for speed.
+// Unlike the Fast*ToBuffer() functions, however, these functions write
+// their output to the beginning of the buffer (hence the name, as the
+// output is left-aligned). The caller is responsible for ensuring that
+// the buffer has enough space to hold the output.
+//
+// Returns a pointer to the end of the string (i.e. the null character
+// terminating the string).
+// ----------------------------------------------------------------------
+
+LIBPROTOBUF_EXPORT char* FastInt32ToBufferLeft(int32 i, char* buffer);
+LIBPROTOBUF_EXPORT char* FastUInt32ToBufferLeft(uint32 i, char* buffer);
+LIBPROTOBUF_EXPORT char* FastInt64ToBufferLeft(int64 i, char* buffer);
+LIBPROTOBUF_EXPORT char* FastUInt64ToBufferLeft(uint64 i, char* buffer);
+
+// Just define these in terms of the above.
+inline char* FastUInt32ToBuffer(uint32 i, char* buffer) {
+ FastUInt32ToBufferLeft(i, buffer);
+ return buffer;
+}
+inline char* FastUInt64ToBuffer(uint64 i, char* buffer) {
+ FastUInt64ToBufferLeft(i, buffer);
+ return buffer;
+}
+
+// ----------------------------------------------------------------------
+// SimpleItoa()
+// Description: converts an integer to a string.
+//
+// Return value: string
+// ----------------------------------------------------------------------
+LIBPROTOBUF_EXPORT string SimpleItoa(int i);
+LIBPROTOBUF_EXPORT string SimpleItoa(unsigned int i);
+LIBPROTOBUF_EXPORT string SimpleItoa(long i);
+LIBPROTOBUF_EXPORT string SimpleItoa(unsigned long i);
+LIBPROTOBUF_EXPORT string SimpleItoa(long long i);
+LIBPROTOBUF_EXPORT string SimpleItoa(unsigned long long i);
+
+// ----------------------------------------------------------------------
+// SimpleDtoa()
+// SimpleFtoa()
+// DoubleToBuffer()
+// FloatToBuffer()
+// Description: converts a double or float to a string which, if
+// passed to NoLocaleStrtod(), will produce the exact same original double
+// (except in case of NaN; all NaNs are considered the same value).
+// We try to keep the string short but it's not guaranteed to be as
+// short as possible.
+//
+// DoubleToBuffer() and FloatToBuffer() write the text to the given
+// buffer and return it. The buffer must be at least
+// kDoubleToBufferSize bytes for doubles and kFloatToBufferSize
+// bytes for floats. kFastToBufferSize is also guaranteed to be large
+// enough to hold either.
+//
+// Return value: string
+// ----------------------------------------------------------------------
+LIBPROTOBUF_EXPORT string SimpleDtoa(double value);
+LIBPROTOBUF_EXPORT string SimpleFtoa(float value);
+
+LIBPROTOBUF_EXPORT char* DoubleToBuffer(double i, char* buffer);
+LIBPROTOBUF_EXPORT char* FloatToBuffer(float i, char* buffer);
+
+// In practice, doubles should never need more than 24 bytes and floats
+// should never need more than 14 (including null terminators), but we
+// overestimate to be safe.
+static const int kDoubleToBufferSize = 32;
+static const int kFloatToBufferSize = 24;
+
+// ----------------------------------------------------------------------
+// ToString() are internal help methods used in StrCat() and Join()
+// ----------------------------------------------------------------------
+namespace internal {
+inline string ToString(int i) {
+ return SimpleItoa(i);
+}
+
+inline string ToString(string a) {
+ return a;
+}
+} // namespace internal
+
+// ----------------------------------------------------------------------
+// StrCat()
+// These methods join some strings together.
+// ----------------------------------------------------------------------
+template <typename T1, typename T2, typename T3, typename T4, typename T5>
+string StrCat(
+ const T1& a, const T2& b, const T3& c, const T4& d, const T5& e) {
+ return internal::ToString(a) + internal::ToString(b) +
+ internal::ToString(c) + internal::ToString(d) + internal::ToString(e);
+}
+
+template <typename T1, typename T2, typename T3, typename T4>
+string StrCat(
+ const T1& a, const T2& b, const T3& c, const T4& d) {
+ return internal::ToString(a) + internal::ToString(b) +
+ internal::ToString(c) + internal::ToString(d);
+}
+
+template <typename T1, typename T2, typename T3>
+string StrCat(const T1& a, const T2& b, const T3& c) {
+ return internal::ToString(a) + internal::ToString(b) +
+ internal::ToString(c);
+}
+
+template <typename T1, typename T2>
+string StrCat(const T1& a, const T2& b) {
+ return internal::ToString(a) + internal::ToString(b);
+}
+
+// ----------------------------------------------------------------------
+// Join()
+// These methods concatenate a range of components into a C++ string, using
+// the C-string "delim" as a separator between components.
+// ----------------------------------------------------------------------
+template <typename Iterator>
+void Join(Iterator start, Iterator end,
+ const char* delim, string* result) {
+ for (Iterator it = start; it != end; ++it) {
+ if (it != start) {
+ result->append(delim);
+ }
+ result->append(internal::ToString(*it));
+ }
+}
+
+template <typename Range>
+string Join(const Range& components,
+ const char* delim) {
+ string result;
+ Join(components.begin(), components.end(), delim, &result);
+ return result;
+}
+
+// ----------------------------------------------------------------------
+// ToHex()
+// Return a lower-case hex string representation of the given integer.
+// ----------------------------------------------------------------------
+LIBPROTOBUF_EXPORT string ToHex(uint64 num);
+
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_STUBS_STRUTIL_H__
diff --git a/contrib/protoc-bnet/google/protobuf/stubs/substitute.cc b/contrib/protoc-bnet/google/protobuf/stubs/substitute.cc
new file mode 100644
index 00000000000..c9d95899f52
--- /dev/null
+++ b/contrib/protoc-bnet/google/protobuf/stubs/substitute.cc
@@ -0,0 +1,134 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+
+#include <google/protobuf/stubs/substitute.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/stl_util.h>
+
+namespace google {
+namespace protobuf {
+namespace strings {
+
+using internal::SubstituteArg;
+
+// Returns the number of args in arg_array which were passed explicitly
+// to Substitute().
+static int CountSubstituteArgs(const SubstituteArg* const* args_array) {
+ int count = 0;
+ while (args_array[count] != NULL && args_array[count]->size() != -1) {
+ ++count;
+ }
+ return count;
+}
+
+string Substitute(
+ const char* format,
+ const SubstituteArg& arg0, const SubstituteArg& arg1,
+ const SubstituteArg& arg2, const SubstituteArg& arg3,
+ const SubstituteArg& arg4, const SubstituteArg& arg5,
+ const SubstituteArg& arg6, const SubstituteArg& arg7,
+ const SubstituteArg& arg8, const SubstituteArg& arg9) {
+ string result;
+ SubstituteAndAppend(&result, format, arg0, arg1, arg2, arg3, arg4,
+ arg5, arg6, arg7, arg8, arg9);
+ return result;
+}
+
+void SubstituteAndAppend(
+ string* output, const char* format,
+ const SubstituteArg& arg0, const SubstituteArg& arg1,
+ const SubstituteArg& arg2, const SubstituteArg& arg3,
+ const SubstituteArg& arg4, const SubstituteArg& arg5,
+ const SubstituteArg& arg6, const SubstituteArg& arg7,
+ const SubstituteArg& arg8, const SubstituteArg& arg9) {
+ const SubstituteArg* const args_array[] = {
+ &arg0, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6, &arg7, &arg8, &arg9, NULL
+ };
+
+ // Determine total size needed.
+ int size = 0;
+ for (int i = 0; format[i] != '\0'; i++) {
+ if (format[i] == '$') {
+ if (ascii_isdigit(format[i+1])) {
+ int index = format[i+1] - '0';
+ if (args_array[index]->size() == -1) {
+ GOOGLE_LOG(DFATAL)
+ << "strings::Substitute format string invalid: asked for \"$"
+ << index << "\", but only " << CountSubstituteArgs(args_array)
+ << " args were given. Full format string was: \""
+ << CEscape(format) << "\".";
+ return;
+ }
+ size += args_array[index]->size();
+ ++i; // Skip next char.
+ } else if (format[i+1] == '$') {
+ ++size;
+ ++i; // Skip next char.
+ } else {
+ GOOGLE_LOG(DFATAL)
+ << "Invalid strings::Substitute() format string: \""
+ << CEscape(format) << "\".";
+ return;
+ }
+ } else {
+ ++size;
+ }
+ }
+
+ if (size == 0) return;
+
+ // Build the string.
+ int original_size = output->size();
+ STLStringResizeUninitialized(output, original_size + size);
+ char* target = string_as_array(output) + original_size;
+ for (int i = 0; format[i] != '\0'; i++) {
+ if (format[i] == '$') {
+ if (ascii_isdigit(format[i+1])) {
+ const SubstituteArg* src = args_array[format[i+1] - '0'];
+ memcpy(target, src->data(), src->size());
+ target += src->size();
+ ++i; // Skip next char.
+ } else if (format[i+1] == '$') {
+ *target++ = '$';
+ ++i; // Skip next char.
+ }
+ } else {
+ *target++ = format[i];
+ }
+ }
+
+ GOOGLE_DCHECK_EQ(target - output->data(), output->size());
+}
+
+} // namespace strings
+} // namespace protobuf
+} // namespace google
diff --git a/contrib/protoc-bnet/google/protobuf/stubs/substitute.h b/contrib/protoc-bnet/google/protobuf/stubs/substitute.h
new file mode 100644
index 00000000000..7ee442af77b
--- /dev/null
+++ b/contrib/protoc-bnet/google/protobuf/stubs/substitute.h
@@ -0,0 +1,170 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// from google3/strings/substitute.h
+
+#include <string>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/strutil.h>
+
+#ifndef GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_
+#define GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_
+
+namespace google {
+namespace protobuf {
+namespace strings {
+
+// ----------------------------------------------------------------------
+// strings::Substitute()
+// strings::SubstituteAndAppend()
+// Kind of like StringPrintf, but different.
+//
+// Example:
+// string GetMessage(string first_name, string last_name, int age) {
+// return strings::Substitute("My name is $0 $1 and I am $2 years old.",
+// first_name, last_name, age);
+// }
+//
+// Differences from StringPrintf:
+// * The format string does not identify the types of arguments.
+// Instead, the magic of C++ deals with this for us. See below
+// for a list of accepted types.
+// * Substitutions in the format string are identified by a '$'
+// followed by a digit. So, you can use arguments out-of-order and
+// use the same argument multiple times.
+// * It's much faster than StringPrintf.
+//
+// Supported types:
+// * Strings (const char*, const string&)
+// * Note that this means you do not have to add .c_str() to all of
+// your strings. In fact, you shouldn't; it will be slower.
+// * int32, int64, uint32, uint64: Formatted using SimpleItoa().
+// * float, double: Formatted using SimpleFtoa() and SimpleDtoa().
+// * bool: Printed as "true" or "false".
+//
+// SubstituteAndAppend() is like Substitute() but appends the result to
+// *output. Example:
+//
+// string str;
+// strings::SubstituteAndAppend(&str,
+// "My name is $0 $1 and I am $2 years old.",
+// first_name, last_name, age);
+//
+// Substitute() is significantly faster than StringPrintf(). For very
+// large strings, it may be orders of magnitude faster.
+// ----------------------------------------------------------------------
+
+namespace internal { // Implementation details.
+
+class SubstituteArg {
+ public:
+ inline SubstituteArg(const char* value)
+ : text_(value), size_(strlen(text_)) {}
+ inline SubstituteArg(const string& value)
+ : text_(value.data()), size_(value.size()) {}
+
+ // Indicates that no argument was given.
+ inline explicit SubstituteArg()
+ : text_(NULL), size_(-1) {}
+
+ // Primitives
+ // We don't overload for signed and unsigned char because if people are
+ // explicitly declaring their chars as signed or unsigned then they are
+ // probably actually using them as 8-bit integers and would probably
+ // prefer an integer representation. But, we don't really know. So, we
+ // make the caller decide what to do.
+ inline SubstituteArg(char value)
+ : text_(scratch_), size_(1) { scratch_[0] = value; }
+ inline SubstituteArg(short value)
+ : text_(FastInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {}
+ inline SubstituteArg(unsigned short value)
+ : text_(FastUInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {}
+ inline SubstituteArg(int value)
+ : text_(FastInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {}
+ inline SubstituteArg(unsigned int value)
+ : text_(FastUInt32ToBuffer(value, scratch_)), size_(strlen(text_)) {}
+ inline SubstituteArg(long value)
+ : text_(FastLongToBuffer(value, scratch_)), size_(strlen(text_)) {}
+ inline SubstituteArg(unsigned long value)
+ : text_(FastULongToBuffer(value, scratch_)), size_(strlen(text_)) {}
+ inline SubstituteArg(long long value)
+ : text_(FastInt64ToBuffer(value, scratch_)), size_(strlen(text_)) {}
+ inline SubstituteArg(unsigned long long value)
+ : text_(FastUInt64ToBuffer(value, scratch_)), size_(strlen(text_)) {}
+ inline SubstituteArg(float value)
+ : text_(FloatToBuffer(value, scratch_)), size_(strlen(text_)) {}
+ inline SubstituteArg(double value)
+ : text_(DoubleToBuffer(value, scratch_)), size_(strlen(text_)) {}
+ inline SubstituteArg(bool value)
+ : text_(value ? "true" : "false"), size_(strlen(text_)) {}
+
+ inline const char* data() const { return text_; }
+ inline int size() const { return size_; }
+
+ private:
+ const char* text_;
+ int size_;
+ char scratch_[kFastToBufferSize];
+};
+
+} // namespace internal
+
+LIBPROTOBUF_EXPORT string Substitute(
+ const char* format,
+ const internal::SubstituteArg& arg0 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg1 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg2 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg3 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg4 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg5 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg6 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg7 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg8 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg9 = internal::SubstituteArg());
+
+LIBPROTOBUF_EXPORT void SubstituteAndAppend(
+ string* output, const char* format,
+ const internal::SubstituteArg& arg0 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg1 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg2 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg3 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg4 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg5 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg6 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg7 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg8 = internal::SubstituteArg(),
+ const internal::SubstituteArg& arg9 = internal::SubstituteArg());
+
+} // namespace strings
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_STUBS_SUBSTITUTE_H_
diff --git a/contrib/protoc-bnet/main.cpp b/contrib/protoc-bnet/main.cpp
new file mode 100644
index 00000000000..7fc55c88293
--- /dev/null
+++ b/contrib/protoc-bnet/main.cpp
@@ -0,0 +1,8 @@
+#include "BnetCodeGenerator.h"
+#include <google/protobuf/compiler/plugin.h>
+
+int main(int argc, char* argv[])
+{
+ BnetCodeGenerator gen;
+ return google::protobuf::compiler::PluginMain(argc, argv, &gen);
+}
diff --git a/contrib/protoc-bnet/method_options.pb.cc b/contrib/protoc-bnet/method_options.pb.cc
new file mode 100644
index 00000000000..ab369b71d76
--- /dev/null
+++ b/contrib/protoc-bnet/method_options.pb.cc
@@ -0,0 +1,86 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: method_options.proto
+
+#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
+#include "method_options.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 Battlenet {
+
+namespace {
+
+
+} // namespace
+
+
+void protobuf_AssignDesc_method_5foptions_2eproto() {
+ protobuf_AddDesc_method_5foptions_2eproto();
+ const ::google::protobuf::FileDescriptor* file =
+ ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(
+ "method_options.proto");
+ GOOGLE_CHECK(file != NULL);
+}
+
+namespace {
+
+GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);
+inline void protobuf_AssignDescriptorsOnce() {
+ ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,
+ &protobuf_AssignDesc_method_5foptions_2eproto);
+}
+
+void protobuf_RegisterTypes(const ::std::string&) {
+ protobuf_AssignDescriptorsOnce();
+}
+
+} // namespace
+
+void protobuf_ShutdownFile_method_5foptions_2eproto() {
+}
+
+void protobuf_AddDesc_method_5foptions_2eproto() {
+ static bool already_here = false;
+ if (already_here) return;
+ already_here = true;
+ GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+ ::google::protobuf::protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
+ "\n\024method_options.proto\022\tBattlenet\032 googl"
+ "e/protobuf/descriptor.proto:3\n\tmethod_id"
+ "\022\036.google.protobuf.MethodOptions\030\320\206\003 \001(\r"
+ "B\002H\002", 124);
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
+ "method_options.proto", &protobuf_RegisterTypes);
+ ::google::protobuf::internal::ExtensionSet::RegisterExtension(
+ &::google::protobuf::MethodOptions::default_instance(),
+ 50000, 13, false, false);
+ ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_method_5foptions_2eproto);
+}
+
+// Force AddDescriptors() to be called at static initialization time.
+struct StaticDescriptorInitializer_method_5foptions_2eproto {
+ StaticDescriptorInitializer_method_5foptions_2eproto() {
+ protobuf_AddDesc_method_5foptions_2eproto();
+ }
+} static_descriptor_initializer_method_5foptions_2eproto_;
+::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::MethodOptions,
+ ::google::protobuf::internal::PrimitiveTypeTraits< ::google::protobuf::uint32 >, 13, false >
+ method_id(kMethodIdFieldNumber, 0u);
+
+// @@protoc_insertion_point(namespace_scope)
+
+} // namespace Battlenet
+
+// @@protoc_insertion_point(global_scope)
diff --git a/contrib/protoc-bnet/method_options.pb.h b/contrib/protoc-bnet/method_options.pb.h
new file mode 100644
index 00000000000..1d375fdc6c9
--- /dev/null
+++ b/contrib/protoc-bnet/method_options.pb.h
@@ -0,0 +1,64 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: method_options.proto
+
+#ifndef PROTOBUF_method_5foptions_2eproto__INCLUDED
+#define PROTOBUF_method_5foptions_2eproto__INCLUDED
+
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+
+#if GOOGLE_PROTOBUF_VERSION < 2006000
+#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 2006001 < 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/generated_message_util.h>
+#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/extension_set.h>
+#include "google/protobuf/descriptor.pb.h"
+// @@protoc_insertion_point(includes)
+
+namespace Battlenet {
+
+// Internal implementation detail -- do not call these.
+void protobuf_AddDesc_method_5foptions_2eproto();
+void protobuf_AssignDesc_method_5foptions_2eproto();
+void protobuf_ShutdownFile_method_5foptions_2eproto();
+
+
+// ===================================================================
+
+
+// ===================================================================
+
+static const int kMethodIdFieldNumber = 50000;
+extern ::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::MethodOptions,
+ ::google::protobuf::internal::PrimitiveTypeTraits< ::google::protobuf::uint32 >, 13, false >
+ method_id;
+
+// ===================================================================
+
+
+// @@protoc_insertion_point(namespace_scope)
+
+} // namespace Battlenet
+
+#ifndef SWIG
+namespace google {
+namespace protobuf {
+
+
+} // namespace google
+} // namespace protobuf
+#endif // SWIG
+
+// @@protoc_insertion_point(global_scope)
+
+#endif // PROTOBUF_method_5foptions_2eproto__INCLUDED
diff --git a/contrib/protoc-bnet/service_options.pb.cc b/contrib/protoc-bnet/service_options.pb.cc
new file mode 100644
index 00000000000..fb5207a1263
--- /dev/null
+++ b/contrib/protoc-bnet/service_options.pb.cc
@@ -0,0 +1,95 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: service_options.proto
+
+#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
+#include "service_options.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 Battlenet {
+
+namespace {
+
+
+} // namespace
+
+
+void protobuf_AssignDesc_service_5foptions_2eproto() {
+ protobuf_AddDesc_service_5foptions_2eproto();
+ const ::google::protobuf::FileDescriptor* file =
+ ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(
+ "service_options.proto");
+ GOOGLE_CHECK(file != NULL);
+}
+
+namespace {
+
+GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);
+inline void protobuf_AssignDescriptorsOnce() {
+ ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,
+ &protobuf_AssignDesc_service_5foptions_2eproto);
+}
+
+void protobuf_RegisterTypes(const ::std::string&) {
+ protobuf_AssignDescriptorsOnce();
+}
+
+} // namespace
+
+void protobuf_ShutdownFile_service_5foptions_2eproto() {
+}
+
+void protobuf_AddDesc_service_5foptions_2eproto() {
+ static bool already_here = false;
+ if (already_here) return;
+ already_here = true;
+ GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+ ::google::protobuf::protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
+ ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
+ "\n\025service_options.proto\022\tBattlenet\032 goog"
+ "le/protobuf/descriptor.proto:R\n(original"
+ "_fully_qualified_descriptor_name\022\037.googl"
+ "e.protobuf.ServiceOptions\030\351\007 \001(\t:5\n\nserv"
+ "ice_id\022\037.google.protobuf.ServiceOptions\030"
+ "\320\206\003 \001(\rB\002H\002", 211);
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
+ "service_options.proto", &protobuf_RegisterTypes);
+ ::google::protobuf::internal::ExtensionSet::RegisterExtension(
+ &::google::protobuf::ServiceOptions::default_instance(),
+ 1001, 9, false, false);
+ ::google::protobuf::internal::ExtensionSet::RegisterExtension(
+ &::google::protobuf::ServiceOptions::default_instance(),
+ 50000, 13, false, false);
+ ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_service_5foptions_2eproto);
+}
+
+// Force AddDescriptors() to be called at static initialization time.
+struct StaticDescriptorInitializer_service_5foptions_2eproto {
+ StaticDescriptorInitializer_service_5foptions_2eproto() {
+ protobuf_AddDesc_service_5foptions_2eproto();
+ }
+} static_descriptor_initializer_service_5foptions_2eproto_;
+const ::std::string original_fully_qualified_descriptor_name_default("");
+::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::ServiceOptions,
+ ::google::protobuf::internal::StringTypeTraits, 9, false >
+ original_fully_qualified_descriptor_name(kOriginalFullyQualifiedDescriptorNameFieldNumber, original_fully_qualified_descriptor_name_default);
+::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::ServiceOptions,
+ ::google::protobuf::internal::PrimitiveTypeTraits< ::google::protobuf::uint32 >, 13, false >
+ service_id(kServiceIdFieldNumber, 0u);
+
+// @@protoc_insertion_point(namespace_scope)
+
+} // namespace Battlenet
+
+// @@protoc_insertion_point(global_scope)
diff --git a/contrib/protoc-bnet/service_options.pb.h b/contrib/protoc-bnet/service_options.pb.h
new file mode 100644
index 00000000000..720ca4c36cd
--- /dev/null
+++ b/contrib/protoc-bnet/service_options.pb.h
@@ -0,0 +1,68 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: service_options.proto
+
+#ifndef PROTOBUF_service_5foptions_2eproto__INCLUDED
+#define PROTOBUF_service_5foptions_2eproto__INCLUDED
+
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+
+#if GOOGLE_PROTOBUF_VERSION < 2006000
+#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 2006001 < 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/generated_message_util.h>
+#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/extension_set.h>
+#include "google/protobuf/descriptor.pb.h"
+// @@protoc_insertion_point(includes)
+
+namespace Battlenet {
+
+// Internal implementation detail -- do not call these.
+void protobuf_AddDesc_service_5foptions_2eproto();
+void protobuf_AssignDesc_service_5foptions_2eproto();
+void protobuf_ShutdownFile_service_5foptions_2eproto();
+
+
+// ===================================================================
+
+
+// ===================================================================
+
+static const int kOriginalFullyQualifiedDescriptorNameFieldNumber = 1001;
+extern ::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::ServiceOptions,
+ ::google::protobuf::internal::StringTypeTraits, 9, false >
+ original_fully_qualified_descriptor_name;
+static const int kServiceIdFieldNumber = 50000;
+extern ::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::ServiceOptions,
+ ::google::protobuf::internal::PrimitiveTypeTraits< ::google::protobuf::uint32 >, 13, false >
+ service_id;
+
+// ===================================================================
+
+
+// @@protoc_insertion_point(namespace_scope)
+
+} // namespace Battlenet
+
+#ifndef SWIG
+namespace google {
+namespace protobuf {
+
+
+} // namespace google
+} // namespace protobuf
+#endif // SWIG
+
+// @@protoc_insertion_point(global_scope)
+
+#endif // PROTOBUF_service_5foptions_2eproto__INCLUDED