mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-15 23:20:36 +01:00
Contrib: Added sources of the protoc plugin used to generate services
This commit is contained in:
68
contrib/protoc-bnet/BnetCodeGenerator.cpp
Normal file
68
contrib/protoc-bnet/BnetCodeGenerator.cpp
Normal file
@@ -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;
|
||||
}
|
||||
|
||||
24
contrib/protoc-bnet/BnetCodeGenerator.h
Normal file
24
contrib/protoc-bnet/BnetCodeGenerator.h
Normal file
@@ -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
|
||||
692
contrib/protoc-bnet/BnetFileGenerator.cpp
Normal file
692
contrib/protoc-bnet/BnetFileGenerator.cpp
Normal file
@@ -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]);
|
||||
}
|
||||
}
|
||||
109
contrib/protoc-bnet/BnetFileGenerator.h
Normal file
109
contrib/protoc-bnet/BnetFileGenerator.h
Normal file
@@ -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__
|
||||
312
contrib/protoc-bnet/BnetServiceGenerator.cpp
Normal file
312
contrib/protoc-bnet/BnetServiceGenerator.cpp
Normal file
@@ -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;
|
||||
}
|
||||
86
contrib/protoc-bnet/BnetServiceGenerator.h
Normal file
86
contrib/protoc-bnet/BnetServiceGenerator.h
Normal file
@@ -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
|
||||
32
contrib/protoc-bnet/CMakeLists.txt
Normal file
32
contrib/protoc-bnet/CMakeLists.txt
Normal file
@@ -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)
|
||||
31
contrib/protoc-bnet/config.h
Normal file
31
contrib/protoc-bnet/config.h
Normal file
@@ -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
|
||||
288
contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_enum.cc
Normal file
288
contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_enum.cc
Normal file
@@ -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
|
||||
103
contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_enum.h
Normal file
103
contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_enum.h
Normal file
@@ -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__
|
||||
@@ -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
|
||||
@@ -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__
|
||||
@@ -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
|
||||
@@ -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__
|
||||
166
contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_field.cc
Normal file
166
contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_field.cc
Normal file
@@ -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
|
||||
185
contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_field.h
Normal file
185
contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_field.h
Normal file
@@ -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__
|
||||
494
contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_helpers.cc
Normal file
494
contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_helpers.cc
Normal file
@@ -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
|
||||
206
contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_helpers.h
Normal file
206
contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_helpers.h
Normal file
@@ -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__
|
||||
2645
contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_message.cc
Normal file
2645
contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_message.cc
Normal file
File diff suppressed because it is too large
Load Diff
175
contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_message.h
Normal file
175
contrib/protoc-bnet/google/protobuf/compiler/cpp/cpp_message.h
Normal file
@@ -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__
|
||||
@@ -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
|
||||
@@ -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__
|
||||
@@ -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__
|
||||
@@ -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
|
||||
@@ -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__
|
||||
@@ -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
|
||||
@@ -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__
|
||||
232
contrib/protoc-bnet/google/protobuf/stubs/hash.h
Normal file
232
contrib/protoc-bnet/google/protobuf/stubs/hash.h
Normal file
@@ -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__
|
||||
1279
contrib/protoc-bnet/google/protobuf/stubs/strutil.cc
Normal file
1279
contrib/protoc-bnet/google/protobuf/stubs/strutil.cc
Normal file
File diff suppressed because it is too large
Load Diff
562
contrib/protoc-bnet/google/protobuf/stubs/strutil.h
Normal file
562
contrib/protoc-bnet/google/protobuf/stubs/strutil.h
Normal file
@@ -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__
|
||||
134
contrib/protoc-bnet/google/protobuf/stubs/substitute.cc
Normal file
134
contrib/protoc-bnet/google/protobuf/stubs/substitute.cc
Normal file
@@ -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
|
||||
170
contrib/protoc-bnet/google/protobuf/stubs/substitute.h
Normal file
170
contrib/protoc-bnet/google/protobuf/stubs/substitute.h
Normal file
@@ -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_
|
||||
8
contrib/protoc-bnet/main.cpp
Normal file
8
contrib/protoc-bnet/main.cpp
Normal file
@@ -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);
|
||||
}
|
||||
86
contrib/protoc-bnet/method_options.pb.cc
Normal file
86
contrib/protoc-bnet/method_options.pb.cc
Normal file
@@ -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)
|
||||
64
contrib/protoc-bnet/method_options.pb.h
Normal file
64
contrib/protoc-bnet/method_options.pb.h
Normal file
@@ -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
|
||||
95
contrib/protoc-bnet/service_options.pb.cc
Normal file
95
contrib/protoc-bnet/service_options.pb.cc
Normal file
@@ -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)
|
||||
68
contrib/protoc-bnet/service_options.pb.h
Normal file
68
contrib/protoc-bnet/service_options.pb.h
Normal file
@@ -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
|
||||
Reference in New Issue
Block a user