Media CAS Proxy SDK release: 16.5.0
This commit is contained in:
199
ubuntu/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
Normal file
199
ubuntu/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
Normal file
@@ -0,0 +1,199 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Author: kenton@google.com (Kenton Varda)
|
||||
// Based on original Protocol Buffers design by
|
||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||
//
|
||||
// This test insures that net/proto2/proto/descriptor.pb.{h,cc} match exactly
|
||||
// what would be generated by the protocol compiler. These files are not
|
||||
// generated automatically at build time because they are compiled into the
|
||||
// protocol compiler itself. So, if they were auto-generated, you'd have a
|
||||
// chicken-and-egg problem.
|
||||
//
|
||||
// If this test fails, run the script
|
||||
// "generate_descriptor_proto.sh" and add
|
||||
// descriptor.pb.{h,cc} to your changelist.
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <google/protobuf/testing/file.h>
|
||||
#include <google/protobuf/testing/file.h>
|
||||
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
|
||||
#include <google/protobuf/compiler/cpp/cpp_generator.h>
|
||||
#include <google/protobuf/compiler/importer.h>
|
||||
#include <google/protobuf/test_util2.h>
|
||||
#include <google/protobuf/io/zero_copy_stream_impl.h>
|
||||
#include <google/protobuf/descriptor.h>
|
||||
#include <google/protobuf/stubs/strutil.h>
|
||||
#include <google/protobuf/testing/googletest.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <google/protobuf/stubs/substitute.h>
|
||||
#include <google/protobuf/stubs/map_util.h>
|
||||
#include <google/protobuf/stubs/stl_util.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace cpp {
|
||||
|
||||
namespace {
|
||||
|
||||
class MockErrorCollector : public MultiFileErrorCollector {
|
||||
public:
|
||||
MockErrorCollector() {}
|
||||
~MockErrorCollector() {}
|
||||
|
||||
std::string text_;
|
||||
|
||||
// implements ErrorCollector ---------------------------------------
|
||||
void AddError(const std::string& filename, int line, int column,
|
||||
const std::string& message) {
|
||||
strings::SubstituteAndAppend(&text_, "$0:$1:$2: $3\n", filename, line, column,
|
||||
message);
|
||||
}
|
||||
};
|
||||
|
||||
class MockGeneratorContext : public GeneratorContext {
|
||||
public:
|
||||
void ExpectFileMatches(const std::string& virtual_filename,
|
||||
const std::string& physical_filename) {
|
||||
auto it = files_.find(virtual_filename);
|
||||
ASSERT_TRUE(it != files_.end())
|
||||
<< "Generator failed to generate file: " << virtual_filename;
|
||||
|
||||
std::string expected_contents = *it->second;
|
||||
std::string actual_contents;
|
||||
GOOGLE_CHECK_OK(
|
||||
File::GetContents(TestUtil::TestSourceDir() + "/" + physical_filename,
|
||||
&actual_contents, true))
|
||||
<< physical_filename;
|
||||
CleanStringLineEndings(&actual_contents, false);
|
||||
|
||||
#ifdef WRITE_FILES // Define to debug mismatched files.
|
||||
GOOGLE_CHECK_OK(File::SetContents("/tmp/expected.cc", expected_contents,
|
||||
true));
|
||||
GOOGLE_CHECK_OK(
|
||||
File::SetContents("/tmp/actual.cc", actual_contents, true));
|
||||
#endif
|
||||
|
||||
ASSERT_EQ(expected_contents, actual_contents)
|
||||
<< physical_filename
|
||||
<< " needs to be regenerated. Please run "
|
||||
"generate_descriptor_proto.sh. "
|
||||
"Then add this file to your CL.";
|
||||
}
|
||||
|
||||
// implements GeneratorContext --------------------------------------
|
||||
|
||||
virtual io::ZeroCopyOutputStream* Open(const std::string& filename) {
|
||||
auto& map_slot = files_[filename];
|
||||
map_slot.reset(new std::string);
|
||||
return new io::StringOutputStream(map_slot.get());
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<std::string, std::unique_ptr<std::string>> files_;
|
||||
};
|
||||
|
||||
const char kDescriptorParameter[] = "dllexport_decl=PROTOBUF_EXPORT";
|
||||
const char kPluginParameter[] = "dllexport_decl=PROTOC_EXPORT";
|
||||
|
||||
|
||||
const char* test_protos[][2] = {
|
||||
{"google/protobuf/descriptor", kDescriptorParameter},
|
||||
{"google/protobuf/compiler/plugin", kPluginParameter},
|
||||
};
|
||||
|
||||
TEST(BootstrapTest, GeneratedFilesMatch) {
|
||||
// We need a mapping from the actual file to virtual and actual path
|
||||
// of the data to compare to.
|
||||
std::map<std::string, std::string> vpath_map;
|
||||
std::map<std::string, std::string> rpath_map;
|
||||
rpath_map
|
||||
["third_party/protobuf_legacy_opensource/src/google/protobuf/"
|
||||
"test_messages_proto2"] =
|
||||
"net/proto2/z_generated_example/test_messages_proto2";
|
||||
rpath_map
|
||||
["third_party/protobuf_legacy_opensource/src/google/protobuf/"
|
||||
"test_messages_proto3"] =
|
||||
"net/proto2/z_generated_example/test_messages_proto3";
|
||||
rpath_map["net/proto2/internal/proto2_weak"] =
|
||||
"net/proto2/z_generated_example/proto2_weak";
|
||||
|
||||
DiskSourceTree source_tree;
|
||||
source_tree.MapPath("", TestUtil::TestSourceDir());
|
||||
|
||||
for (auto file_parameter : test_protos) {
|
||||
MockErrorCollector error_collector;
|
||||
Importer importer(&source_tree, &error_collector);
|
||||
const FileDescriptor* file =
|
||||
importer.Import(file_parameter[0] + std::string(".proto"));
|
||||
ASSERT_TRUE(file != nullptr)
|
||||
<< "Can't import file " << file_parameter[0] + std::string(".proto")
|
||||
<< "\n";
|
||||
EXPECT_EQ("", error_collector.text_);
|
||||
CppGenerator generator;
|
||||
MockGeneratorContext context;
|
||||
#ifdef GOOGLE_PROTOBUF_RUNTIME_INCLUDE_BASE
|
||||
generator.set_opensource_runtime(true);
|
||||
generator.set_runtime_include_base(GOOGLE_PROTOBUF_RUNTIME_INCLUDE_BASE);
|
||||
#endif
|
||||
std::string error;
|
||||
ASSERT_TRUE(generator.Generate(file, file_parameter[1], &context, &error));
|
||||
|
||||
std::string vpath =
|
||||
FindWithDefault(vpath_map, file_parameter[0], file_parameter[0]);
|
||||
std::string rpath =
|
||||
FindWithDefault(rpath_map, file_parameter[0], file_parameter[0]);
|
||||
context.ExpectFileMatches(vpath + ".pb.cc", rpath + ".pb.cc");
|
||||
context.ExpectFileMatches(vpath + ".pb.h", rpath + ".pb.h");
|
||||
}
|
||||
}
|
||||
|
||||
// test Generate in cpp_generator.cc
|
||||
TEST(BootstrapTest, OptionNotExist) {
|
||||
cpp::CppGenerator generator;
|
||||
DescriptorPool pool;
|
||||
GeneratorContext* generator_context = nullptr;
|
||||
std::string parameter = "aaa";
|
||||
std::string error;
|
||||
ASSERT_FALSE(generator.Generate(
|
||||
pool.FindFileByName("google/protobuf/descriptor.proto"), parameter,
|
||||
generator_context, &error));
|
||||
EXPECT_EQ(error, "Unknown generator option: " + parameter);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
434
ubuntu/google/protobuf/compiler/cpp/cpp_enum.cc
Normal file
434
ubuntu/google/protobuf/compiler/cpp/cpp_enum.cc
Normal file
@@ -0,0 +1,434 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Author: kenton@google.com (Kenton Varda)
|
||||
// Based on original Protocol Buffers design by
|
||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <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;
|
||||
}
|
||||
|
||||
// Returns the number of unique numeric enum values. This is less than
|
||||
// descriptor->value_count() when there are aliased values.
|
||||
int CountUniqueValues(const EnumDescriptor* descriptor) {
|
||||
std::set<int> values;
|
||||
for (int i = 0; i < descriptor->value_count(); ++i) {
|
||||
values.insert(descriptor->value(i)->number());
|
||||
}
|
||||
return values.size();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor,
|
||||
const std::map<std::string, std::string>& vars,
|
||||
const Options& options)
|
||||
: descriptor_(descriptor),
|
||||
classname_(ClassName(descriptor, false)),
|
||||
options_(options),
|
||||
generate_array_size_(ShouldGenerateArraySize(descriptor)),
|
||||
variables_(vars) {
|
||||
variables_["classname"] = classname_;
|
||||
variables_["classtype"] = QualifiedClassName(descriptor_, options);
|
||||
variables_["short_name"] = descriptor_->name();
|
||||
variables_["nested_name"] = descriptor_->name();
|
||||
variables_["resolved_name"] = ResolveKeyword(descriptor_->name());
|
||||
variables_["prefix"] =
|
||||
(descriptor_->containing_type() == NULL) ? "" : classname_ + "_";
|
||||
}
|
||||
|
||||
EnumGenerator::~EnumGenerator() {}
|
||||
|
||||
void EnumGenerator::GenerateDefinition(io::Printer* printer) {
|
||||
Formatter format(printer, variables_);
|
||||
format("enum ${1$$classname$$}$ : int {\n", descriptor_);
|
||||
format.Indent();
|
||||
|
||||
const EnumValueDescriptor* min_value = descriptor_->value(0);
|
||||
const EnumValueDescriptor* max_value = descriptor_->value(0);
|
||||
|
||||
for (int i = 0; i < descriptor_->value_count(); i++) {
|
||||
auto format_value = format;
|
||||
format_value.Set("name", EnumValueName(descriptor_->value(i)));
|
||||
// In C++, an value of -2147483648 gets interpreted as the negative of
|
||||
// 2147483648, and since 2147483648 can't fit in an integer, this produces a
|
||||
// compiler warning. This works around that issue.
|
||||
format_value.Set("number", Int32ToString(descriptor_->value(i)->number()));
|
||||
format_value.Set("deprecation",
|
||||
DeprecatedAttribute(options_, descriptor_->value(i)));
|
||||
|
||||
if (i > 0) format_value(",\n");
|
||||
format_value("${1$$prefix$$name$$}$ $deprecation$= $number$",
|
||||
descriptor_->value(i));
|
||||
|
||||
if (descriptor_->value(i)->number() < min_value->number()) {
|
||||
min_value = descriptor_->value(i);
|
||||
}
|
||||
if (descriptor_->value(i)->number() > max_value->number()) {
|
||||
max_value = descriptor_->value(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (descriptor_->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) {
|
||||
// For new enum semantics: generate min and max sentinel values equal to
|
||||
// INT32_MIN and INT32_MAX
|
||||
if (descriptor_->value_count() > 0) format(",\n");
|
||||
format(
|
||||
"$classname$_$prefix$INT_MIN_SENTINEL_DO_NOT_USE_ = "
|
||||
"std::numeric_limits<$int32$>::min(),\n"
|
||||
"$classname$_$prefix$INT_MAX_SENTINEL_DO_NOT_USE_ = "
|
||||
"std::numeric_limits<$int32$>::max()");
|
||||
}
|
||||
|
||||
format.Outdent();
|
||||
format("\n};\n");
|
||||
|
||||
format(
|
||||
"$dllexport_decl $bool $classname$_IsValid(int value);\n"
|
||||
"constexpr $classname$ ${1$$prefix$$short_name$_MIN$}$ = "
|
||||
"$prefix$$2$;\n"
|
||||
"constexpr $classname$ ${1$$prefix$$short_name$_MAX$}$ = "
|
||||
"$prefix$$3$;\n",
|
||||
descriptor_, EnumValueName(min_value), EnumValueName(max_value));
|
||||
|
||||
if (generate_array_size_) {
|
||||
format(
|
||||
"constexpr int ${1$$prefix$$short_name$_ARRAYSIZE$}$ = "
|
||||
"$prefix$$short_name$_MAX + 1;\n\n",
|
||||
descriptor_);
|
||||
}
|
||||
|
||||
if (HasDescriptorMethods(descriptor_->file(), options_)) {
|
||||
format(
|
||||
"$dllexport_decl $const ::$proto_ns$::EnumDescriptor* "
|
||||
"$classname$_descriptor();\n");
|
||||
}
|
||||
|
||||
// The _Name and _Parse functions. The lite implementation is table-based, so
|
||||
// we make sure to keep the tables hidden in the .cc file.
|
||||
if (!HasDescriptorMethods(descriptor_->file(), options_)) {
|
||||
format("const std::string& $classname$_Name($classname$ value);\n");
|
||||
}
|
||||
// The _Name() function accepts the enum type itself but also any integral
|
||||
// type.
|
||||
format(
|
||||
"template<typename T>\n"
|
||||
"inline const std::string& $classname$_Name(T enum_t_value) {\n"
|
||||
" static_assert(::std::is_same<T, $classname$>::value ||\n"
|
||||
" ::std::is_integral<T>::value,\n"
|
||||
" \"Incorrect type passed to function $classname$_Name.\");\n");
|
||||
if (HasDescriptorMethods(descriptor_->file(), options_)) {
|
||||
format(
|
||||
" return ::$proto_ns$::internal::NameOfEnum(\n"
|
||||
" $classname$_descriptor(), enum_t_value);\n");
|
||||
} else {
|
||||
format(
|
||||
" return $classname$_Name(static_cast<$classname$>(enum_t_value));\n");
|
||||
}
|
||||
format("}\n");
|
||||
|
||||
if (HasDescriptorMethods(descriptor_->file(), options_)) {
|
||||
format(
|
||||
"inline bool $classname$_Parse(\n"
|
||||
" ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, $classname$* "
|
||||
"value) "
|
||||
"{\n"
|
||||
" return ::$proto_ns$::internal::ParseNamedEnum<$classname$>(\n"
|
||||
" $classname$_descriptor(), name, value);\n"
|
||||
"}\n");
|
||||
} else {
|
||||
format(
|
||||
"bool $classname$_Parse(\n"
|
||||
" ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, $classname$* "
|
||||
"value);\n");
|
||||
}
|
||||
}
|
||||
|
||||
void EnumGenerator::GenerateGetEnumDescriptorSpecializations(
|
||||
io::Printer* printer) {
|
||||
Formatter format(printer, variables_);
|
||||
format(
|
||||
"template <> struct is_proto_enum< $classtype$> : ::std::true_type "
|
||||
"{};\n");
|
||||
if (HasDescriptorMethods(descriptor_->file(), options_)) {
|
||||
format(
|
||||
"template <>\n"
|
||||
"inline const EnumDescriptor* GetEnumDescriptor< $classtype$>() {\n"
|
||||
" return $classtype$_descriptor();\n"
|
||||
"}\n");
|
||||
}
|
||||
}
|
||||
|
||||
void EnumGenerator::GenerateSymbolImports(io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("typedef $classname$ $resolved_name$;\n");
|
||||
|
||||
for (int j = 0; j < descriptor_->value_count(); j++) {
|
||||
std::string deprecated_attr =
|
||||
DeprecatedAttribute(options_, descriptor_->value(j));
|
||||
format(
|
||||
"$1$static constexpr $resolved_name$ ${2$$3$$}$ =\n"
|
||||
" $classname$_$3$;\n",
|
||||
deprecated_attr, descriptor_->value(j),
|
||||
EnumValueName(descriptor_->value(j)));
|
||||
}
|
||||
|
||||
format(
|
||||
"static inline bool $nested_name$_IsValid(int value) {\n"
|
||||
" return $classname$_IsValid(value);\n"
|
||||
"}\n"
|
||||
"static constexpr $resolved_name$ ${1$$nested_name$_MIN$}$ =\n"
|
||||
" $classname$_$nested_name$_MIN;\n"
|
||||
"static constexpr $resolved_name$ ${1$$nested_name$_MAX$}$ =\n"
|
||||
" $classname$_$nested_name$_MAX;\n",
|
||||
descriptor_);
|
||||
if (generate_array_size_) {
|
||||
format(
|
||||
"static constexpr int ${1$$nested_name$_ARRAYSIZE$}$ =\n"
|
||||
" $classname$_$nested_name$_ARRAYSIZE;\n",
|
||||
descriptor_);
|
||||
}
|
||||
|
||||
if (HasDescriptorMethods(descriptor_->file(), options_)) {
|
||||
format(
|
||||
"static inline const ::$proto_ns$::EnumDescriptor*\n"
|
||||
"$nested_name$_descriptor() {\n"
|
||||
" return $classname$_descriptor();\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
format(
|
||||
"template<typename T>\n"
|
||||
"static inline const std::string& $nested_name$_Name(T enum_t_value) {\n"
|
||||
" static_assert(::std::is_same<T, $resolved_name$>::value ||\n"
|
||||
" ::std::is_integral<T>::value,\n"
|
||||
" \"Incorrect type passed to function $nested_name$_Name.\");\n"
|
||||
" return $classname$_Name(enum_t_value);\n"
|
||||
"}\n");
|
||||
format(
|
||||
"static inline bool "
|
||||
"$nested_name$_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name,\n"
|
||||
" $resolved_name$* value) {\n"
|
||||
" return $classname$_Parse(name, value);\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
void EnumGenerator::GenerateMethods(int idx, io::Printer* printer) {
|
||||
Formatter format(printer, variables_);
|
||||
if (HasDescriptorMethods(descriptor_->file(), options_)) {
|
||||
format(
|
||||
"const ::$proto_ns$::EnumDescriptor* $classname$_descriptor() {\n"
|
||||
" ::$proto_ns$::internal::AssignDescriptors(&$desc_table$);\n"
|
||||
" return $file_level_enum_descriptors$[$1$];\n"
|
||||
"}\n",
|
||||
idx);
|
||||
}
|
||||
|
||||
format(
|
||||
"bool $classname$_IsValid(int value) {\n"
|
||||
" switch (value) {\n");
|
||||
|
||||
// Multiple values may have the same number. Make sure we only cover
|
||||
// each number once by first constructing a set containing all valid
|
||||
// numbers, then printing a case statement for each element.
|
||||
|
||||
std::set<int> numbers;
|
||||
for (int j = 0; j < descriptor_->value_count(); j++) {
|
||||
const EnumValueDescriptor* value = descriptor_->value(j);
|
||||
numbers.insert(value->number());
|
||||
}
|
||||
|
||||
for (std::set<int>::iterator iter = numbers.begin(); iter != numbers.end();
|
||||
++iter) {
|
||||
format(" case $1$:\n", Int32ToString(*iter));
|
||||
}
|
||||
|
||||
format(
|
||||
" return true;\n"
|
||||
" default:\n"
|
||||
" return false;\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"\n");
|
||||
|
||||
if (!HasDescriptorMethods(descriptor_->file(), options_)) {
|
||||
// In lite mode (where descriptors are unavailable), we generate separate
|
||||
// tables for mapping between enum names and numbers. The _entries table
|
||||
// contains the bulk of the data and is sorted by name, while
|
||||
// _entries_by_number is sorted by number and just contains pointers into
|
||||
// _entries. The two tables allow mapping from name to number and number to
|
||||
// name, both in time logarithmic in the number of enum entries. This could
|
||||
// probably be made faster, but for now the tables are intended to be simple
|
||||
// and compact.
|
||||
//
|
||||
// Enums with allow_alias = true support multiple entries with the same
|
||||
// numerical value. In cases where there are multiple names for the same
|
||||
// number, we treat the first name appearing in the .proto file as the
|
||||
// canonical one.
|
||||
std::map<std::string, int> name_to_number;
|
||||
std::map<int, std::string> number_to_canonical_name;
|
||||
for (int i = 0; i < descriptor_->value_count(); i++) {
|
||||
const EnumValueDescriptor* value = descriptor_->value(i);
|
||||
name_to_number.emplace(value->name(), value->number());
|
||||
// The same number may appear with multiple names, so we use emplace() to
|
||||
// let the first name win.
|
||||
number_to_canonical_name.emplace(value->number(), value->name());
|
||||
}
|
||||
|
||||
format(
|
||||
"static ::$proto_ns$::internal::ExplicitlyConstructed<std::string> "
|
||||
"$classname$_strings[$1$] = {};\n\n",
|
||||
CountUniqueValues(descriptor_));
|
||||
|
||||
// We concatenate all the names for a given enum into one big string
|
||||
// literal. If instead we store an array of string literals, the linker
|
||||
// seems to put all enum strings for a given .proto file in the same
|
||||
// section, which hinders its ability to strip out unused strings.
|
||||
format("static const char $classname$_names[] =");
|
||||
for (const auto& p : name_to_number) {
|
||||
format("\n \"$1$\"", p.first);
|
||||
}
|
||||
format(";\n\n");
|
||||
|
||||
format(
|
||||
"static const ::$proto_ns$::internal::EnumEntry $classname$_entries[] "
|
||||
"= {\n");
|
||||
int i = 0;
|
||||
std::map<int, int> number_to_index;
|
||||
int data_index = 0;
|
||||
for (const auto& p : name_to_number) {
|
||||
format(" { {$classname$_names + $1$, $2$}, $3$ },\n", data_index,
|
||||
p.first.size(), p.second);
|
||||
if (number_to_canonical_name[p.second] == p.first) {
|
||||
number_to_index.emplace(p.second, i);
|
||||
}
|
||||
++i;
|
||||
data_index += p.first.size();
|
||||
}
|
||||
|
||||
format(
|
||||
"};\n"
|
||||
"\n"
|
||||
"static const int $classname$_entries_by_number[] = {\n");
|
||||
for (const auto& p : number_to_index) {
|
||||
format(" $1$, // $2$ -> $3$\n", p.second, p.first,
|
||||
number_to_canonical_name[p.first]);
|
||||
}
|
||||
format(
|
||||
"};\n"
|
||||
"\n");
|
||||
|
||||
format(
|
||||
"const std::string& $classname$_Name(\n"
|
||||
" $classname$ value) {\n"
|
||||
" static const bool dummy =\n"
|
||||
" ::$proto_ns$::internal::InitializeEnumStrings(\n"
|
||||
" $classname$_entries,\n"
|
||||
" $classname$_entries_by_number,\n"
|
||||
" $1$, $classname$_strings);\n"
|
||||
" (void) dummy;\n"
|
||||
" int idx = ::$proto_ns$::internal::LookUpEnumName(\n"
|
||||
" $classname$_entries,\n"
|
||||
" $classname$_entries_by_number,\n"
|
||||
" $1$, value);\n"
|
||||
" return idx == -1 ? ::$proto_ns$::internal::GetEmptyString() :\n"
|
||||
" $classname$_strings[idx].get();\n"
|
||||
"}\n",
|
||||
CountUniqueValues(descriptor_));
|
||||
format(
|
||||
"bool $classname$_Parse(\n"
|
||||
" ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, $classname$* "
|
||||
"value) "
|
||||
"{\n"
|
||||
" int int_value;\n"
|
||||
" bool success = ::$proto_ns$::internal::LookUpEnumValue(\n"
|
||||
" $classname$_entries, $1$, name, &int_value);\n"
|
||||
" if (success) {\n"
|
||||
" *value = static_cast<$classname$>(int_value);\n"
|
||||
" }\n"
|
||||
" return success;\n"
|
||||
"}\n",
|
||||
descriptor_->value_count());
|
||||
}
|
||||
|
||||
if (descriptor_->containing_type() != NULL) {
|
||||
std::string parent = ClassName(descriptor_->containing_type(), false);
|
||||
// Before C++17, we must define the static constants which were
|
||||
// declared in the header, to give the linker a place to put them.
|
||||
// But pre-2015 MSVC++ insists that we not.
|
||||
format(
|
||||
"#if (__cplusplus < 201703) && "
|
||||
"(!defined(_MSC_VER) || _MSC_VER >= 1900)\n");
|
||||
|
||||
for (int i = 0; i < descriptor_->value_count(); i++) {
|
||||
format("constexpr $classname$ $1$::$2$;\n", parent,
|
||||
EnumValueName(descriptor_->value(i)));
|
||||
}
|
||||
format(
|
||||
"constexpr $classname$ $1$::$nested_name$_MIN;\n"
|
||||
"constexpr $classname$ $1$::$nested_name$_MAX;\n",
|
||||
parent);
|
||||
if (generate_array_size_) {
|
||||
format("constexpr int $1$::$nested_name$_ARRAYSIZE;\n", parent);
|
||||
}
|
||||
|
||||
format(
|
||||
"#endif // (__cplusplus < 201703) && "
|
||||
"(!defined(_MSC_VER) || _MSC_VER >= 1900)\n");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
105
ubuntu/google/protobuf/compiler/cpp/cpp_enum.h
Normal file
105
ubuntu/google/protobuf/compiler/cpp/cpp_enum.h
Normal file
@@ -0,0 +1,105 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Author: kenton@google.com (Kenton Varda)
|
||||
// Based on original Protocol Buffers design by
|
||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__
|
||||
#define GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <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 google
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace cpp {
|
||||
|
||||
class EnumGenerator {
|
||||
public:
|
||||
// See generator.cc for the meaning of dllexport_decl.
|
||||
EnumGenerator(const EnumDescriptor* descriptor,
|
||||
const std::map<std::string, std::string>& vars,
|
||||
const Options& options);
|
||||
~EnumGenerator();
|
||||
|
||||
// Generate header code defining the enum. This code should be placed
|
||||
// within the enum's package namespace, but NOT within any class, even for
|
||||
// nested enums.
|
||||
void GenerateDefinition(io::Printer* printer);
|
||||
|
||||
// Generate specialization of GetEnumDescriptor<MyEnum>().
|
||||
// Precondition: in ::google::protobuf namespace.
|
||||
void GenerateGetEnumDescriptorSpecializations(io::Printer* printer);
|
||||
|
||||
// For enums nested within a message, generate code to import all the enum's
|
||||
// symbols (e.g. the enum type name, all its values, etc.) into the class's
|
||||
// namespace. This should be placed inside the class definition in the
|
||||
// header.
|
||||
void GenerateSymbolImports(io::Printer* printer) const;
|
||||
|
||||
// Source file stuff.
|
||||
|
||||
// Generate non-inline methods related to the enum, such as IsValidValue().
|
||||
// Goes in the .cc file. EnumDescriptors are stored in an array, idx is
|
||||
// the index in this array that corresponds with this enum.
|
||||
void GenerateMethods(int idx, io::Printer* printer);
|
||||
|
||||
private:
|
||||
const EnumDescriptor* descriptor_;
|
||||
const std::string classname_;
|
||||
const Options& options_;
|
||||
// whether to generate the *_ARRAYSIZE constant.
|
||||
const bool generate_array_size_;
|
||||
|
||||
std::map<std::string, std::string> variables_;
|
||||
|
||||
friend class FileGenerator;
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator);
|
||||
};
|
||||
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__
|
||||
490
ubuntu/google/protobuf/compiler/cpp/cpp_enum_field.cc
Normal file
490
ubuntu/google/protobuf/compiler/cpp/cpp_enum_field.cc
Normal file
@@ -0,0 +1,490 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 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/wire_format.h>
|
||||
#include <google/protobuf/stubs/strutil.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace cpp {
|
||||
|
||||
namespace {
|
||||
|
||||
void SetEnumVariables(const FieldDescriptor* descriptor,
|
||||
std::map<std::string, std::string>* variables,
|
||||
const Options& options) {
|
||||
SetCommonFieldVariables(descriptor, variables, options);
|
||||
const EnumValueDescriptor* default_value = descriptor->default_value_enum();
|
||||
(*variables)["type"] = QualifiedClassName(descriptor->enum_type(), options);
|
||||
(*variables)["default"] = Int32ToString(default_value->number());
|
||||
(*variables)["full_name"] = descriptor->full_name();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// ===================================================================
|
||||
|
||||
EnumFieldGenerator::EnumFieldGenerator(const FieldDescriptor* descriptor,
|
||||
const Options& options)
|
||||
: FieldGenerator(descriptor, options) {
|
||||
SetEnumVariables(descriptor, &variables_, options);
|
||||
}
|
||||
|
||||
EnumFieldGenerator::~EnumFieldGenerator() {}
|
||||
|
||||
void EnumFieldGenerator::GeneratePrivateMembers(io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("int $name$_;\n");
|
||||
}
|
||||
|
||||
void EnumFieldGenerator::GenerateAccessorDeclarations(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format(
|
||||
"$deprecated_attr$$type$ ${1$$name$$}$() const;\n"
|
||||
"$deprecated_attr$void ${1$set_$name$$}$($type$ value);\n"
|
||||
"private:\n"
|
||||
"$type$ ${1$_internal_$name$$}$() const;\n"
|
||||
"void ${1$_internal_set_$name$$}$($type$ value);\n"
|
||||
"public:\n",
|
||||
descriptor_);
|
||||
}
|
||||
|
||||
void EnumFieldGenerator::GenerateInlineAccessorDefinitions(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format(
|
||||
"inline $type$ $classname$::_internal_$name$() const {\n"
|
||||
" return static_cast< $type$ >($name$_);\n"
|
||||
"}\n"
|
||||
"inline $type$ $classname$::$name$() const {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_get:$full_name$)\n"
|
||||
" return _internal_$name$();\n"
|
||||
"}\n"
|
||||
"inline void $classname$::_internal_set_$name$($type$ value) {\n");
|
||||
if (!HasPreservingUnknownEnumSemantics(descriptor_)) {
|
||||
format(" assert($type$_IsValid(value));\n");
|
||||
}
|
||||
format(
|
||||
" $set_hasbit$\n"
|
||||
" $name$_ = value;\n"
|
||||
"}\n"
|
||||
"inline void $classname$::set_$name$($type$ value) {\n"
|
||||
"$annotate_accessor$"
|
||||
" _internal_set_$name$(value);\n"
|
||||
" // @@protoc_insertion_point(field_set:$full_name$)\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
void EnumFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("$name$_ = $default$;\n");
|
||||
}
|
||||
|
||||
void EnumFieldGenerator::GenerateMergingCode(io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("_internal_set_$name$(from._internal_$name$());\n");
|
||||
}
|
||||
|
||||
void EnumFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("swap($name$_, other->$name$_);\n");
|
||||
}
|
||||
|
||||
void EnumFieldGenerator::GenerateConstructorCode(io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("$name$_ = $default$;\n");
|
||||
}
|
||||
|
||||
void EnumFieldGenerator::GenerateCopyConstructorCode(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("$name$_ = from.$name$_;\n");
|
||||
}
|
||||
|
||||
void EnumFieldGenerator::GenerateSerializeWithCachedSizesToArray(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format(
|
||||
"target = stream->EnsureSpace(target);\n"
|
||||
"target = ::$proto_ns$::internal::WireFormatLite::WriteEnumToArray(\n"
|
||||
" $number$, this->_internal_$name$(), target);\n");
|
||||
}
|
||||
|
||||
void EnumFieldGenerator::GenerateByteSize(io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format(
|
||||
"total_size += $tag_size$ +\n"
|
||||
" "
|
||||
"::$proto_ns$::internal::WireFormatLite::EnumSize(this->_internal_$name$("
|
||||
"));\n");
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
|
||||
EnumOneofFieldGenerator::EnumOneofFieldGenerator(
|
||||
const FieldDescriptor* descriptor, const Options& options)
|
||||
: EnumFieldGenerator(descriptor, options) {
|
||||
SetCommonOneofFieldVariables(descriptor, &variables_);
|
||||
}
|
||||
|
||||
EnumOneofFieldGenerator::~EnumOneofFieldGenerator() {}
|
||||
|
||||
void EnumOneofFieldGenerator::GenerateInlineAccessorDefinitions(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format(
|
||||
"inline $type$ $classname$::_internal_$name$() const {\n"
|
||||
" if (_internal_has_$name$()) {\n"
|
||||
" return static_cast< $type$ >($field_member$);\n"
|
||||
" }\n"
|
||||
" return static_cast< $type$ >($default$);\n"
|
||||
"}\n"
|
||||
"inline $type$ $classname$::$name$() const {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_get:$full_name$)\n"
|
||||
" return _internal_$name$();\n"
|
||||
"}\n"
|
||||
"inline void $classname$::_internal_set_$name$($type$ value) {\n");
|
||||
if (!HasPreservingUnknownEnumSemantics(descriptor_)) {
|
||||
format(" assert($type$_IsValid(value));\n");
|
||||
}
|
||||
format(
|
||||
" if (!_internal_has_$name$()) {\n"
|
||||
" clear_$oneof_name$();\n"
|
||||
" set_has_$name$();\n"
|
||||
" }\n"
|
||||
" $field_member$ = value;\n"
|
||||
"}\n"
|
||||
"inline void $classname$::set_$name$($type$ value) {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_set:$full_name$)\n"
|
||||
" _internal_set_$name$(value);\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
void EnumOneofFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("$field_member$ = $default$;\n");
|
||||
}
|
||||
|
||||
void EnumOneofFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
|
||||
// Don't print any swapping code. Swapping the union will swap this field.
|
||||
}
|
||||
|
||||
void EnumOneofFieldGenerator::GenerateConstructorCode(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("$ns$::_$classname$_default_instance_.$name$_ = $default$;\n");
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
|
||||
RepeatedEnumFieldGenerator::RepeatedEnumFieldGenerator(
|
||||
const FieldDescriptor* descriptor, const Options& options)
|
||||
: FieldGenerator(descriptor, options) {
|
||||
SetEnumVariables(descriptor, &variables_, options);
|
||||
}
|
||||
|
||||
RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {}
|
||||
|
||||
void RepeatedEnumFieldGenerator::GeneratePrivateMembers(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("::$proto_ns$::RepeatedField<int> $name$_;\n");
|
||||
if (descriptor_->is_packed() &&
|
||||
HasGeneratedMethods(descriptor_->file(), options_)) {
|
||||
format("mutable std::atomic<int> _$name$_cached_byte_size_;\n");
|
||||
}
|
||||
}
|
||||
|
||||
void RepeatedEnumFieldGenerator::GenerateAccessorDeclarations(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format(
|
||||
"private:\n"
|
||||
"$type$ ${1$_internal_$name$$}$(int index) const;\n"
|
||||
"void ${1$_internal_add_$name$$}$($type$ value);\n"
|
||||
"::$proto_ns$::RepeatedField<int>* "
|
||||
"${1$_internal_mutable_$name$$}$();\n"
|
||||
"public:\n"
|
||||
"$deprecated_attr$$type$ ${1$$name$$}$(int index) const;\n"
|
||||
"$deprecated_attr$void ${1$set_$name$$}$(int index, $type$ value);\n"
|
||||
"$deprecated_attr$void ${1$add_$name$$}$($type$ value);\n"
|
||||
"$deprecated_attr$const ::$proto_ns$::RepeatedField<int>& "
|
||||
"${1$$name$$}$() const;\n"
|
||||
"$deprecated_attr$::$proto_ns$::RepeatedField<int>* "
|
||||
"${1$mutable_$name$$}$();\n",
|
||||
descriptor_);
|
||||
}
|
||||
|
||||
void RepeatedEnumFieldGenerator::GenerateInlineAccessorDefinitions(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format(
|
||||
"inline $type$ $classname$::_internal_$name$(int index) const {\n"
|
||||
" return static_cast< $type$ >($name$_.Get(index));\n"
|
||||
"}\n"
|
||||
"inline $type$ $classname$::$name$(int index) const {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_get:$full_name$)\n"
|
||||
" return _internal_$name$(index);\n"
|
||||
"}\n"
|
||||
"inline void $classname$::set_$name$(int index, $type$ value) {\n"
|
||||
"$annotate_accessor$");
|
||||
if (!HasPreservingUnknownEnumSemantics(descriptor_)) {
|
||||
format(" assert($type$_IsValid(value));\n");
|
||||
}
|
||||
format(
|
||||
" $name$_.Set(index, value);\n"
|
||||
" // @@protoc_insertion_point(field_set:$full_name$)\n"
|
||||
"}\n"
|
||||
"inline void $classname$::_internal_add_$name$($type$ value) {\n");
|
||||
if (!HasPreservingUnknownEnumSemantics(descriptor_)) {
|
||||
format(" assert($type$_IsValid(value));\n");
|
||||
}
|
||||
format(
|
||||
" $name$_.Add(value);\n"
|
||||
"}\n"
|
||||
"inline void $classname$::add_$name$($type$ value) {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_add:$full_name$)\n"
|
||||
" _internal_add_$name$(value);\n"
|
||||
"}\n"
|
||||
"inline const ::$proto_ns$::RepeatedField<int>&\n"
|
||||
"$classname$::$name$() const {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_list:$full_name$)\n"
|
||||
" return $name$_;\n"
|
||||
"}\n"
|
||||
"inline ::$proto_ns$::RepeatedField<int>*\n"
|
||||
"$classname$::_internal_mutable_$name$() {\n"
|
||||
" return &$name$_;\n"
|
||||
"}\n"
|
||||
"inline ::$proto_ns$::RepeatedField<int>*\n"
|
||||
"$classname$::mutable_$name$() {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
|
||||
" return _internal_mutable_$name$();\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
void RepeatedEnumFieldGenerator::GenerateClearingCode(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("$name$_.Clear();\n");
|
||||
}
|
||||
|
||||
void RepeatedEnumFieldGenerator::GenerateMergingCode(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("$name$_.MergeFrom(from.$name$_);\n");
|
||||
}
|
||||
|
||||
void RepeatedEnumFieldGenerator::GenerateSwappingCode(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("$name$_.InternalSwap(&other->$name$_);\n");
|
||||
}
|
||||
|
||||
void RepeatedEnumFieldGenerator::GenerateConstructorCode(
|
||||
io::Printer* printer) const {
|
||||
// Not needed for repeated fields.
|
||||
}
|
||||
|
||||
void RepeatedEnumFieldGenerator::GenerateMergeFromCodedStream(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
// Don't use ReadRepeatedPrimitive here so that the enum can be validated.
|
||||
format(
|
||||
"int value = 0;\n"
|
||||
"DO_((::$proto_ns$::internal::WireFormatLite::ReadPrimitive<\n"
|
||||
" int, ::$proto_ns$::internal::WireFormatLite::TYPE_ENUM>(\n"
|
||||
" input, &value)));\n");
|
||||
if (HasPreservingUnknownEnumSemantics(descriptor_)) {
|
||||
format("add_$name$(static_cast< $type$ >(value));\n");
|
||||
} else {
|
||||
format(
|
||||
"if ($type$_IsValid(value)) {\n"
|
||||
" add_$name$(static_cast< $type$ >(value));\n");
|
||||
if (UseUnknownFieldSet(descriptor_->file(), options_)) {
|
||||
format(
|
||||
"} else {\n"
|
||||
" mutable_unknown_fields()->AddVarint(\n"
|
||||
" $number$, static_cast<$uint64$>(value));\n");
|
||||
} else {
|
||||
format(
|
||||
"} else {\n"
|
||||
" unknown_fields_stream.WriteVarint32(tag);\n"
|
||||
" unknown_fields_stream.WriteVarint32(\n"
|
||||
" static_cast<$uint32$>(value));\n");
|
||||
}
|
||||
format("}\n");
|
||||
}
|
||||
}
|
||||
|
||||
void RepeatedEnumFieldGenerator::GenerateMergeFromCodedStreamWithPacking(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
if (!descriptor_->is_packed()) {
|
||||
// This path is rarely executed, so we use a non-inlined implementation.
|
||||
if (HasPreservingUnknownEnumSemantics(descriptor_)) {
|
||||
format(
|
||||
"DO_((::$proto_ns$::internal::"
|
||||
"WireFormatLite::ReadPackedEnumPreserveUnknowns(\n"
|
||||
" input,\n"
|
||||
" $number$,\n"
|
||||
" nullptr,\n"
|
||||
" nullptr,\n"
|
||||
" this->_internal_mutable_$name$())));\n");
|
||||
} else if (UseUnknownFieldSet(descriptor_->file(), options_)) {
|
||||
format(
|
||||
"DO_((::$proto_ns$::internal::WireFormat::"
|
||||
"ReadPackedEnumPreserveUnknowns(\n"
|
||||
" input,\n"
|
||||
" $number$,\n"
|
||||
" $type$_IsValid,\n"
|
||||
" mutable_unknown_fields(),\n"
|
||||
" this->_internal_mutable_$name$())));\n");
|
||||
} else {
|
||||
format(
|
||||
"DO_((::$proto_ns$::internal::"
|
||||
"WireFormatLite::ReadPackedEnumPreserveUnknowns(\n"
|
||||
" input,\n"
|
||||
" $number$,\n"
|
||||
" $type$_IsValid,\n"
|
||||
" &unknown_fields_stream,\n"
|
||||
" this->_internal_mutable_$name$())));\n");
|
||||
}
|
||||
} else {
|
||||
format(
|
||||
"$uint32$ length;\n"
|
||||
"DO_(input->ReadVarint32(&length));\n"
|
||||
"::$proto_ns$::io::CodedInputStream::Limit limit = "
|
||||
"input->PushLimit(static_cast<int>(length));\n"
|
||||
"while (input->BytesUntilLimit() > 0) {\n"
|
||||
" int value = 0;\n"
|
||||
" DO_((::$proto_ns$::internal::WireFormatLite::ReadPrimitive<\n"
|
||||
" int, ::$proto_ns$::internal::WireFormatLite::TYPE_ENUM>(\n"
|
||||
" input, &value)));\n");
|
||||
if (HasPreservingUnknownEnumSemantics(descriptor_)) {
|
||||
format(" add_$name$(static_cast< $type$ >(value));\n");
|
||||
} else {
|
||||
format(
|
||||
" if ($type$_IsValid(value)) {\n"
|
||||
" _internal_add_$name$(static_cast< $type$ >(value));\n"
|
||||
" } else {\n");
|
||||
if (UseUnknownFieldSet(descriptor_->file(), options_)) {
|
||||
format(
|
||||
" mutable_unknown_fields()->AddVarint(\n"
|
||||
" $number$, static_cast<$uint64$>(value));\n");
|
||||
} else {
|
||||
format(
|
||||
" unknown_fields_stream.WriteVarint32(tag);\n"
|
||||
" unknown_fields_stream.WriteVarint32(\n"
|
||||
" static_cast<$uint32$>(value));\n");
|
||||
}
|
||||
format(" }\n");
|
||||
}
|
||||
format(
|
||||
"}\n"
|
||||
"input->PopLimit(limit);\n");
|
||||
}
|
||||
}
|
||||
|
||||
void RepeatedEnumFieldGenerator::GenerateSerializeWithCachedSizesToArray(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
if (descriptor_->is_packed()) {
|
||||
// Write the tag and the size.
|
||||
format(
|
||||
"{\n"
|
||||
" int byte_size = "
|
||||
"_$name$_cached_byte_size_.load(std::memory_order_relaxed);\n"
|
||||
" if (byte_size > 0) {\n"
|
||||
" target = stream->WriteEnumPacked(\n"
|
||||
" $number$, $name$_, byte_size, target);\n"
|
||||
" }\n"
|
||||
"}\n");
|
||||
} else {
|
||||
format(
|
||||
"for (int i = 0, n = this->_internal_$name$_size(); i < n; i++) {\n"
|
||||
" target = stream->EnsureSpace(target);\n"
|
||||
" target = ::$proto_ns$::internal::WireFormatLite::WriteEnumToArray(\n"
|
||||
" $number$, this->_internal_$name$(i), target);\n"
|
||||
"}\n");
|
||||
}
|
||||
}
|
||||
|
||||
void RepeatedEnumFieldGenerator::GenerateByteSize(io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format(
|
||||
"{\n"
|
||||
" size_t data_size = 0;\n"
|
||||
" unsigned int count = static_cast<unsigned "
|
||||
"int>(this->_internal_$name$_size());");
|
||||
format.Indent();
|
||||
format(
|
||||
"for (unsigned int i = 0; i < count; i++) {\n"
|
||||
" data_size += ::$proto_ns$::internal::WireFormatLite::EnumSize(\n"
|
||||
" this->_internal_$name$(static_cast<int>(i)));\n"
|
||||
"}\n");
|
||||
|
||||
if (descriptor_->is_packed()) {
|
||||
format(
|
||||
"if (data_size > 0) {\n"
|
||||
" total_size += $tag_size$ +\n"
|
||||
" ::$proto_ns$::internal::WireFormatLite::Int32Size(\n"
|
||||
" static_cast<$int32$>(data_size));\n"
|
||||
"}\n"
|
||||
"int cached_size = ::$proto_ns$::internal::ToCachedSize(data_size);\n"
|
||||
"_$name$_cached_byte_size_.store(cached_size,\n"
|
||||
" std::memory_order_relaxed);\n"
|
||||
"total_size += data_size;\n");
|
||||
} else {
|
||||
format("total_size += ($tag_size$UL * count) + data_size;\n");
|
||||
}
|
||||
format.Outdent();
|
||||
format("}\n");
|
||||
}
|
||||
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
113
ubuntu/google/protobuf/compiler/cpp/cpp_enum_field.h
Normal file
113
ubuntu/google/protobuf/compiler/cpp/cpp_enum_field.h
Normal file
@@ -0,0 +1,113 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Author: kenton@google.com (Kenton Varda)
|
||||
// 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:
|
||||
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 GenerateCopyConstructorCode(io::Printer* printer) const;
|
||||
void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
|
||||
void GenerateByteSize(io::Printer* printer) const;
|
||||
|
||||
private:
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator);
|
||||
};
|
||||
|
||||
class EnumOneofFieldGenerator : public EnumFieldGenerator {
|
||||
public:
|
||||
EnumOneofFieldGenerator(const FieldDescriptor* descriptor,
|
||||
const Options& options);
|
||||
~EnumOneofFieldGenerator();
|
||||
|
||||
// implements FieldGenerator ---------------------------------------
|
||||
void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
|
||||
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:
|
||||
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 GenerateCopyConstructorCode(io::Printer* printer) const {}
|
||||
void GenerateMergeFromCodedStream(io::Printer* printer) const;
|
||||
void GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const;
|
||||
void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
|
||||
void GenerateByteSize(io::Printer* printer) const;
|
||||
|
||||
private:
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedEnumFieldGenerator);
|
||||
};
|
||||
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_FIELD_H__
|
||||
187
ubuntu/google/protobuf/compiler/cpp/cpp_extension.cc
Normal file
187
ubuntu/google/protobuf/compiler/cpp/cpp_extension.cc
Normal file
@@ -0,0 +1,187 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// 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/descriptor.pb.h>
|
||||
#include <google/protobuf/io/printer.h>
|
||||
#include <google/protobuf/stubs/strutil.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.
|
||||
std::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(options_, descriptor_->cpp_type()));
|
||||
type_traits_.append(" >");
|
||||
break;
|
||||
}
|
||||
SetCommonVars(options, &variables_);
|
||||
variables_["extendee"] = ExtendeeClassName(descriptor_);
|
||||
variables_["type_traits"] = type_traits_;
|
||||
std::string name = descriptor_->name();
|
||||
variables_["name"] = ResolveKeyword(name);
|
||||
variables_["constant_name"] = FieldConstantName(descriptor_);
|
||||
variables_["field_type"] =
|
||||
StrCat(static_cast<int>(descriptor_->type()));
|
||||
variables_["packed"] = descriptor_->is_packed() ? "true" : "false";
|
||||
|
||||
std::string scope =
|
||||
IsScoped() ? ClassName(descriptor_->extension_scope(), false) + "::" : "";
|
||||
variables_["scope"] = scope;
|
||||
std::string scoped_name = scope + ResolveKeyword(name);
|
||||
variables_["scoped_name"] = scoped_name;
|
||||
variables_["number"] = StrCat(descriptor_->number());
|
||||
}
|
||||
|
||||
ExtensionGenerator::~ExtensionGenerator() {}
|
||||
|
||||
bool ExtensionGenerator::IsScoped() const {
|
||||
return descriptor_->extension_scope() != nullptr;
|
||||
}
|
||||
|
||||
void ExtensionGenerator::GenerateDeclaration(io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
|
||||
// If this is a class member, it needs to be declared "static". Otherwise,
|
||||
// it needs to be "extern". In the latter case, it also needs the DLL
|
||||
// export/import specifier.
|
||||
std::string qualifier;
|
||||
if (!IsScoped()) {
|
||||
qualifier = "extern";
|
||||
if (!options_.dllexport_decl.empty()) {
|
||||
qualifier = options_.dllexport_decl + " " + qualifier;
|
||||
}
|
||||
} else {
|
||||
qualifier = "static";
|
||||
}
|
||||
|
||||
format(
|
||||
"static const int $constant_name$ = $number$;\n"
|
||||
"$1$ ::$proto_ns$::internal::ExtensionIdentifier< $extendee$,\n"
|
||||
" ::$proto_ns$::internal::$type_traits$, $field_type$, $packed$ >\n"
|
||||
" ${2$$name$$}$;\n",
|
||||
qualifier, descriptor_);
|
||||
}
|
||||
|
||||
void ExtensionGenerator::GenerateDefinition(io::Printer* printer) {
|
||||
// If we are building for lite with implicit weak fields, we want to skip over
|
||||
// any custom options (i.e. extensions of messages from descriptor.proto).
|
||||
// This prevents the creation of any unnecessary linker references to the
|
||||
// descriptor messages.
|
||||
if (options_.lite_implicit_weak_fields &&
|
||||
descriptor_->containing_type()->file()->name() ==
|
||||
"net/proto2/proto/descriptor.proto") {
|
||||
return;
|
||||
}
|
||||
|
||||
Formatter format(printer, variables_);
|
||||
std::string default_str;
|
||||
// If this is a class member, it needs to be declared in its class scope.
|
||||
if (descriptor_->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
|
||||
// We need to declare a global string which will contain the default value.
|
||||
// We cannot declare it at class scope because that would require exposing
|
||||
// it in the header which would be annoying for other reasons. So we
|
||||
// replace :: with _ in the name and declare it as a global.
|
||||
default_str =
|
||||
StringReplace(variables_["scoped_name"], "::", "_", true) + "_default";
|
||||
format("const std::string $1$($2$);\n", default_str,
|
||||
DefaultValue(options_, descriptor_));
|
||||
} else if (descriptor_->message_type()) {
|
||||
// We have to initialize the default instance for extensions at registration
|
||||
// time.
|
||||
default_str =
|
||||
FieldMessageTypeName(descriptor_, options_) + "::default_instance()";
|
||||
} else {
|
||||
default_str = DefaultValue(options_, descriptor_);
|
||||
}
|
||||
|
||||
// Likewise, class members need to declare the field constant variable.
|
||||
if (IsScoped()) {
|
||||
format(
|
||||
"#if !defined(_MSC_VER) || _MSC_VER >= 1900\n"
|
||||
"const int $scope$$constant_name$;\n"
|
||||
"#endif\n");
|
||||
}
|
||||
|
||||
format(
|
||||
"::$proto_ns$::internal::ExtensionIdentifier< $extendee$,\n"
|
||||
" ::$proto_ns$::internal::$type_traits$, $field_type$, $packed$ >\n"
|
||||
" $scoped_name$($constant_name$, $1$);\n",
|
||||
default_str);
|
||||
}
|
||||
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
91
ubuntu/google/protobuf/compiler/cpp/cpp_extension.h
Normal file
91
ubuntu/google/protobuf/compiler/cpp/cpp_extension.h
Normal file
@@ -0,0 +1,91 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Author: kenton@google.com (Kenton Varda)
|
||||
// Based on original Protocol Buffers design by
|
||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_EXTENSION_H__
|
||||
#define GOOGLE_PROTOBUF_COMPILER_CPP_EXTENSION_H__
|
||||
|
||||
#include <map>
|
||||
#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 google
|
||||
|
||||
namespace google {
|
||||
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* descriptor,
|
||||
const Options& options);
|
||||
~ExtensionGenerator();
|
||||
|
||||
// Header stuff.
|
||||
void GenerateDeclaration(io::Printer* printer) const;
|
||||
|
||||
// Source file stuff.
|
||||
void GenerateDefinition(io::Printer* printer);
|
||||
|
||||
bool IsScoped() const;
|
||||
|
||||
private:
|
||||
const FieldDescriptor* descriptor_;
|
||||
std::string type_traits_;
|
||||
Options options_;
|
||||
|
||||
std::map<std::string, std::string> variables_;
|
||||
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator);
|
||||
};
|
||||
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__
|
||||
195
ubuntu/google/protobuf/compiler/cpp/cpp_field.cc
Normal file
195
ubuntu/google/protobuf/compiler/cpp/cpp_field.cc
Normal file
@@ -0,0 +1,195 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Author: kenton@google.com (Kenton Varda)
|
||||
// Based on original Protocol Buffers design by
|
||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||
|
||||
#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/stubs/logging.h>
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
#include <google/protobuf/compiler/cpp/cpp_enum_field.h>
|
||||
#include <google/protobuf/compiler/cpp/cpp_map_field.h>
|
||||
#include <google/protobuf/compiler/cpp/cpp_message_field.h>
|
||||
#include <google/protobuf/descriptor.pb.h>
|
||||
#include <google/protobuf/io/printer.h>
|
||||
#include <google/protobuf/wire_format.h>
|
||||
#include <google/protobuf/stubs/strutil.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace cpp {
|
||||
|
||||
using internal::WireFormat;
|
||||
|
||||
void SetCommonFieldVariables(const FieldDescriptor* descriptor,
|
||||
std::map<std::string, std::string>* variables,
|
||||
const Options& options) {
|
||||
SetCommonVars(options, variables);
|
||||
(*variables)["ns"] = Namespace(descriptor, options);
|
||||
(*variables)["name"] = FieldName(descriptor);
|
||||
(*variables)["index"] = StrCat(descriptor->index());
|
||||
(*variables)["number"] = StrCat(descriptor->number());
|
||||
(*variables)["classname"] = ClassName(FieldScope(descriptor), false);
|
||||
(*variables)["declared_type"] = DeclaredTypeMethodName(descriptor->type());
|
||||
(*variables)["field_member"] = FieldName(descriptor) + "_";
|
||||
|
||||
(*variables)["tag_size"] = StrCat(
|
||||
WireFormat::TagSize(descriptor->number(), descriptor->type()));
|
||||
(*variables)["deprecated_attr"] = DeprecatedAttribute(options, descriptor);
|
||||
|
||||
(*variables)["set_hasbit"] = "";
|
||||
(*variables)["clear_hasbit"] = "";
|
||||
if (HasHasbit(descriptor)) {
|
||||
(*variables)["set_hasbit_io"] =
|
||||
"_Internal::set_has_" + FieldName(descriptor) + "(&_has_bits_);";
|
||||
} else {
|
||||
(*variables)["set_hasbit_io"] = "";
|
||||
}
|
||||
(*variables)["annotate_accessor"] = "";
|
||||
|
||||
// These variables are placeholders to pick out the beginning and ends of
|
||||
// identifiers for annotations (when doing so with existing variables would
|
||||
// be ambiguous or impossible). They should never be set to anything but the
|
||||
// empty string.
|
||||
(*variables)["{"] = "";
|
||||
(*variables)["}"] = "";
|
||||
}
|
||||
|
||||
void FieldGenerator::SetHasBitIndex(int32 has_bit_index) {
|
||||
if (!HasHasbit(descriptor_)) {
|
||||
GOOGLE_CHECK_EQ(has_bit_index, -1);
|
||||
return;
|
||||
}
|
||||
variables_["set_hasbit"] = StrCat(
|
||||
"_has_bits_[", has_bit_index / 32, "] |= 0x",
|
||||
strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8), "u;");
|
||||
variables_["clear_hasbit"] = StrCat(
|
||||
"_has_bits_[", has_bit_index / 32, "] &= ~0x",
|
||||
strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8), "u;");
|
||||
}
|
||||
|
||||
void SetCommonOneofFieldVariables(
|
||||
const FieldDescriptor* descriptor,
|
||||
std::map<std::string, std::string>* variables) {
|
||||
const std::string prefix = descriptor->containing_oneof()->name() + "_.";
|
||||
(*variables)["oneof_name"] = descriptor->containing_oneof()->name();
|
||||
(*variables)["field_member"] =
|
||||
StrCat(prefix, (*variables)["name"], "_");
|
||||
}
|
||||
|
||||
FieldGenerator::~FieldGenerator() {}
|
||||
|
||||
FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor,
|
||||
const Options& options,
|
||||
MessageSCCAnalyzer* scc_analyzer)
|
||||
: descriptor_(descriptor), field_generators_(descriptor->field_count()) {
|
||||
// Construct all the FieldGenerators.
|
||||
for (int i = 0; i < descriptor->field_count(); i++) {
|
||||
field_generators_[i].reset(
|
||||
MakeGenerator(descriptor->field(i), options, scc_analyzer));
|
||||
}
|
||||
}
|
||||
|
||||
FieldGenerator* FieldGeneratorMap::MakeGoogleInternalGenerator(
|
||||
const FieldDescriptor* field, const Options& options,
|
||||
MessageSCCAnalyzer* scc_analyzer) {
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FieldGenerator* FieldGeneratorMap::MakeGenerator(
|
||||
const FieldDescriptor* field, const Options& options,
|
||||
MessageSCCAnalyzer* scc_analyzer) {
|
||||
FieldGenerator* generator =
|
||||
MakeGoogleInternalGenerator(field, options, scc_analyzer);
|
||||
if (generator) {
|
||||
return generator;
|
||||
}
|
||||
|
||||
if (field->is_repeated()) {
|
||||
switch (field->cpp_type()) {
|
||||
case FieldDescriptor::CPPTYPE_MESSAGE:
|
||||
if (field->is_map()) {
|
||||
return new MapFieldGenerator(field, options);
|
||||
} else {
|
||||
return new RepeatedMessageFieldGenerator(field, options,
|
||||
scc_analyzer);
|
||||
}
|
||||
case FieldDescriptor::CPPTYPE_STRING:
|
||||
return new RepeatedStringFieldGenerator(field, options);
|
||||
case FieldDescriptor::CPPTYPE_ENUM:
|
||||
return new RepeatedEnumFieldGenerator(field, options);
|
||||
default:
|
||||
return new RepeatedPrimitiveFieldGenerator(field, options);
|
||||
}
|
||||
} else if (field->real_containing_oneof()) {
|
||||
switch (field->cpp_type()) {
|
||||
case FieldDescriptor::CPPTYPE_MESSAGE:
|
||||
return new MessageOneofFieldGenerator(field, options, scc_analyzer);
|
||||
case FieldDescriptor::CPPTYPE_STRING:
|
||||
return new StringOneofFieldGenerator(field, options);
|
||||
case FieldDescriptor::CPPTYPE_ENUM:
|
||||
return new EnumOneofFieldGenerator(field, options);
|
||||
default:
|
||||
return new PrimitiveOneofFieldGenerator(field, options);
|
||||
}
|
||||
} else {
|
||||
switch (field->cpp_type()) {
|
||||
case FieldDescriptor::CPPTYPE_MESSAGE:
|
||||
return new MessageFieldGenerator(field, options, scc_analyzer);
|
||||
case FieldDescriptor::CPPTYPE_STRING:
|
||||
return new StringFieldGenerator(field, options);
|
||||
case FieldDescriptor::CPPTYPE_ENUM:
|
||||
return new EnumFieldGenerator(field, options);
|
||||
default:
|
||||
return new PrimitiveFieldGenerator(field, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FieldGeneratorMap::~FieldGeneratorMap() {}
|
||||
|
||||
const FieldGenerator& FieldGeneratorMap::get(
|
||||
const FieldDescriptor* field) const {
|
||||
GOOGLE_CHECK_EQ(field->containing_type(), descriptor_);
|
||||
return *field_generators_[field->index()];
|
||||
}
|
||||
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
222
ubuntu/google/protobuf/compiler/cpp/cpp_field.h
Normal file
222
ubuntu/google/protobuf/compiler/cpp/cpp_field.h
Normal file
@@ -0,0 +1,222 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 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/compiler/cpp/cpp_helpers.h>
|
||||
#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 google
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace cpp {
|
||||
|
||||
// Helper function: set variables in the map that are the same for all
|
||||
// field code generators.
|
||||
// ['name', 'index', 'number', 'classname', 'declared_type', 'tag_size',
|
||||
// 'deprecation'].
|
||||
void SetCommonFieldVariables(const FieldDescriptor* descriptor,
|
||||
std::map<std::string, std::string>* variables,
|
||||
const Options& options);
|
||||
|
||||
void SetCommonOneofFieldVariables(
|
||||
const FieldDescriptor* descriptor,
|
||||
std::map<std::string, std::string>* variables);
|
||||
|
||||
class FieldGenerator {
|
||||
public:
|
||||
explicit FieldGenerator(const FieldDescriptor* descriptor,
|
||||
const Options& options)
|
||||
: descriptor_(descriptor), options_(options) {}
|
||||
virtual ~FieldGenerator();
|
||||
virtual void GenerateSerializeWithCachedSizes(
|
||||
io::Printer* printer) const final{};
|
||||
// Generate lines of code declaring members fields of the message class
|
||||
// needed to represent this field. These are placed inside the message
|
||||
// class.
|
||||
virtual void GeneratePrivateMembers(io::Printer* printer) const = 0;
|
||||
|
||||
// Generate static default variable for this field. These are placed inside
|
||||
// the message class. Most field types don't need this, so the default
|
||||
// implementation is empty.
|
||||
virtual void GenerateStaticMembers(io::Printer* /*printer*/) const {}
|
||||
|
||||
// Generate prototypes for all of the accessor functions related to this
|
||||
// field. These are placed inside the class definition.
|
||||
virtual void GenerateAccessorDeclarations(io::Printer* printer) const = 0;
|
||||
|
||||
// Generate inline definitions of accessor functions for this field.
|
||||
// These are placed inside the header after all class definitions.
|
||||
virtual void GenerateInlineAccessorDefinitions(
|
||||
io::Printer* printer) const = 0;
|
||||
|
||||
// Generate definitions of accessors that aren't inlined. These are
|
||||
// placed somewhere in the .cc file.
|
||||
// Most field types don't need this, so the default implementation is empty.
|
||||
virtual void GenerateNonInlineAccessorDefinitions(
|
||||
io::Printer* /*printer*/) const {}
|
||||
|
||||
// Generate declarations of accessors that are for internal purposes only.
|
||||
// Most field types don't need this, so the default implementation is empty.
|
||||
virtual void GenerateInternalAccessorDefinitions(
|
||||
io::Printer* /*printer*/) const {}
|
||||
|
||||
// Generate definitions of accessors that are for internal purposes only.
|
||||
// Most field types don't need this, so the default implementation is empty.
|
||||
virtual void GenerateInternalAccessorDeclarations(
|
||||
io::Printer* /*printer*/) const {}
|
||||
|
||||
// Generate lines of code (statements, not declarations) which clear the
|
||||
// field. This is used to define the clear_$name$() method
|
||||
virtual void GenerateClearingCode(io::Printer* printer) const = 0;
|
||||
|
||||
// Generate lines of code (statements, not declarations) which clear the
|
||||
// field as part of the Clear() method for the whole message. For message
|
||||
// types which have field presence bits, MessageGenerator::GenerateClear
|
||||
// will have already checked the presence bits.
|
||||
//
|
||||
// Since most field types can re-use GenerateClearingCode, this method is
|
||||
// not pure virtual.
|
||||
virtual void GenerateMessageClearingCode(io::Printer* printer) const {
|
||||
GenerateClearingCode(printer);
|
||||
}
|
||||
|
||||
// Generate lines of code (statements, not declarations) which merges the
|
||||
// contents of the field from the current message to the target message,
|
||||
// which is stored in the generated code variable "from".
|
||||
// This is used to fill in the MergeFrom method for the whole message.
|
||||
// Details of this usage can be found in message.cc under the
|
||||
// GenerateMergeFrom method.
|
||||
virtual void GenerateMergingCode(io::Printer* printer) const = 0;
|
||||
|
||||
// Generates a copy constructor
|
||||
virtual void GenerateCopyConstructorCode(io::Printer* printer) const = 0;
|
||||
|
||||
// Generate lines of code (statements, not declarations) which swaps
|
||||
// this field and the corresponding field of another message, which
|
||||
// is stored in the generated code variable "other". This is used to
|
||||
// define the Swap method. Details of usage can be found in
|
||||
// message.cc under the GenerateSwap method.
|
||||
virtual void GenerateSwappingCode(io::Printer* printer) const = 0;
|
||||
|
||||
// Generate initialization code for private members declared by
|
||||
// GeneratePrivateMembers(). These go into the message class's SharedCtor()
|
||||
// method, invoked by each of the generated constructors.
|
||||
virtual void GenerateConstructorCode(io::Printer* printer) const = 0;
|
||||
|
||||
// Generate any code that needs to go in the class's SharedDtor() method,
|
||||
// invoked by the destructor.
|
||||
// Most field types don't need this, so the default implementation is empty.
|
||||
virtual void GenerateDestructorCode(io::Printer* /*printer*/) const {}
|
||||
|
||||
// Generate a manual destructor invocation for use when the message is on an
|
||||
// arena. The code that this method generates will be executed inside a
|
||||
// shared-for-the-whole-message-class method registered with
|
||||
// OwnDestructor(). The method should return |true| if it generated any code
|
||||
// that requires a call; this allows the message generator to eliminate the
|
||||
// OwnDestructor() registration if no fields require it.
|
||||
virtual bool GenerateArenaDestructorCode(io::Printer* printer) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Generate 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;
|
||||
|
||||
void SetHasBitIndex(int32 has_bit_index);
|
||||
|
||||
protected:
|
||||
const FieldDescriptor* descriptor_;
|
||||
const Options& options_;
|
||||
std::map<std::string, std::string> variables_;
|
||||
|
||||
private:
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGenerator);
|
||||
};
|
||||
|
||||
// Convenience class which constructs FieldGenerators for a Descriptor.
|
||||
class FieldGeneratorMap {
|
||||
public:
|
||||
FieldGeneratorMap(const Descriptor* descriptor, const Options& options,
|
||||
MessageSCCAnalyzer* scc_analyzer);
|
||||
~FieldGeneratorMap();
|
||||
|
||||
const FieldGenerator& get(const FieldDescriptor* field) const;
|
||||
|
||||
void SetHasBitIndices(const std::vector<int>& has_bit_indices_) {
|
||||
for (int i = 0; i < descriptor_->field_count(); ++i) {
|
||||
field_generators_[i]->SetHasBitIndex(has_bit_indices_[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const Descriptor* descriptor_;
|
||||
std::vector<std::unique_ptr<FieldGenerator>> field_generators_;
|
||||
|
||||
static FieldGenerator* MakeGoogleInternalGenerator(
|
||||
const FieldDescriptor* field, const Options& options,
|
||||
MessageSCCAnalyzer* scc_analyzer);
|
||||
static FieldGenerator* MakeGenerator(const FieldDescriptor* field,
|
||||
const Options& options,
|
||||
MessageSCCAnalyzer* scc_analyzer);
|
||||
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap);
|
||||
};
|
||||
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_CPP_FIELD_H__
|
||||
1507
ubuntu/google/protobuf/compiler/cpp/cpp_file.cc
Normal file
1507
ubuntu/google/protobuf/compiler/cpp/cpp_file.cc
Normal file
File diff suppressed because it is too large
Load Diff
206
ubuntu/google/protobuf/compiler/cpp/cpp_file.h
Normal file
206
ubuntu/google/protobuf/compiler/cpp/cpp_file.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_FILE_H__
|
||||
#define GOOGLE_PROTOBUF_COMPILER_CPP_FILE_H__
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
#include <google/protobuf/compiler/cpp/cpp_field.h>
|
||||
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
|
||||
#include <google/protobuf/compiler/cpp/cpp_options.h>
|
||||
#include <google/protobuf/compiler/scc.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
class FileDescriptor; // descriptor.h
|
||||
namespace io {
|
||||
class Printer; // printer.h
|
||||
}
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace cpp {
|
||||
|
||||
class EnumGenerator; // enum.h
|
||||
class MessageGenerator; // message.h
|
||||
class ServiceGenerator; // service.h
|
||||
class ExtensionGenerator; // extension.h
|
||||
|
||||
class FileGenerator {
|
||||
public:
|
||||
// See generator.cc for the meaning of dllexport_decl.
|
||||
FileGenerator(const FileDescriptor* file, const Options& options);
|
||||
~FileGenerator();
|
||||
|
||||
// Shared code between the two header generators below.
|
||||
void GenerateHeader(io::Printer* printer);
|
||||
|
||||
// info_path, if non-empty, should be the path (relative to printer's
|
||||
// output) to the metadata file describing this proto header.
|
||||
void GenerateProtoHeader(io::Printer* printer, const std::string& info_path);
|
||||
// info_path, if non-empty, should be the path (relative to printer's
|
||||
// output) to the metadata file describing this PB header.
|
||||
void GeneratePBHeader(io::Printer* printer, const std::string& info_path);
|
||||
void GenerateSource(io::Printer* printer);
|
||||
|
||||
int NumMessages() const { return message_generators_.size(); }
|
||||
// Similar to GenerateSource but generates only one message
|
||||
void GenerateSourceForMessage(int idx, io::Printer* printer);
|
||||
void GenerateGlobalSource(io::Printer* printer);
|
||||
|
||||
private:
|
||||
// Internal type used by GenerateForwardDeclarations (defined in file.cc).
|
||||
class ForwardDeclarations;
|
||||
struct CrossFileReferences;
|
||||
|
||||
void IncludeFile(const std::string& google3_name, io::Printer* printer) {
|
||||
DoIncludeFile(google3_name, false, printer);
|
||||
}
|
||||
void IncludeFileAndExport(const std::string& google3_name,
|
||||
io::Printer* printer) {
|
||||
DoIncludeFile(google3_name, true, printer);
|
||||
}
|
||||
void DoIncludeFile(const std::string& google3_name, bool do_export,
|
||||
io::Printer* printer);
|
||||
|
||||
std::string CreateHeaderInclude(const std::string& basename,
|
||||
const FileDescriptor* file);
|
||||
void GetCrossFileReferencesForField(const FieldDescriptor* field,
|
||||
CrossFileReferences* refs);
|
||||
void GetCrossFileReferencesForFile(const FileDescriptor* file,
|
||||
CrossFileReferences* refs);
|
||||
void GenerateInternalForwardDeclarations(const CrossFileReferences& refs,
|
||||
io::Printer* printer);
|
||||
void GenerateSourceIncludes(io::Printer* printer);
|
||||
void GenerateSourceDefaultInstance(int idx, io::Printer* printer);
|
||||
|
||||
void GenerateInitForSCC(const SCC* scc, const CrossFileReferences& refs,
|
||||
io::Printer* printer);
|
||||
void GenerateTables(io::Printer* printer);
|
||||
void GenerateReflectionInitializationCode(io::Printer* printer);
|
||||
|
||||
// For other imports, generates their forward-declarations.
|
||||
void GenerateForwardDeclarations(io::Printer* printer);
|
||||
|
||||
// Generates top or bottom of a header file.
|
||||
void GenerateTopHeaderGuard(io::Printer* printer, bool pb_h);
|
||||
void GenerateBottomHeaderGuard(io::Printer* printer, bool pb_h);
|
||||
|
||||
// Generates #include directives.
|
||||
void GenerateLibraryIncludes(io::Printer* printer);
|
||||
void GenerateDependencyIncludes(io::Printer* printer);
|
||||
|
||||
// Generate a pragma to pull in metadata using the given info_path (if
|
||||
// non-empty). info_path should be relative to printer's output.
|
||||
void GenerateMetadataPragma(io::Printer* printer,
|
||||
const std::string& info_path);
|
||||
|
||||
// Generates a couple of different pieces before definitions:
|
||||
void GenerateGlobalStateFunctionDeclarations(io::Printer* printer);
|
||||
|
||||
// Generates types for classes.
|
||||
void GenerateMessageDefinitions(io::Printer* printer);
|
||||
|
||||
void GenerateEnumDefinitions(io::Printer* printer);
|
||||
|
||||
// Generates generic service definitions.
|
||||
void GenerateServiceDefinitions(io::Printer* printer);
|
||||
|
||||
// Generates extension identifiers.
|
||||
void GenerateExtensionIdentifiers(io::Printer* printer);
|
||||
|
||||
// Generates inline function definitions.
|
||||
void GenerateInlineFunctionDefinitions(io::Printer* printer);
|
||||
|
||||
void GenerateProto2NamespaceEnumSpecializations(io::Printer* printer);
|
||||
|
||||
// Sometimes the names we use in a .proto file happen to be defined as
|
||||
// macros on some platforms (e.g., macro/minor used in plugin.proto are
|
||||
// defined as macros in sys/types.h on FreeBSD and a few other platforms).
|
||||
// To make the generated code compile on these platforms, we either have to
|
||||
// undef the macro for these few platforms, or rename the field name for all
|
||||
// platforms. Since these names are part of protobuf public API, renaming is
|
||||
// generally a breaking change so we prefer the #undef approach.
|
||||
void GenerateMacroUndefs(io::Printer* printer);
|
||||
|
||||
bool IsSCCRepresentative(const Descriptor* d) {
|
||||
return GetSCCRepresentative(d) == d;
|
||||
}
|
||||
const Descriptor* GetSCCRepresentative(const Descriptor* d) {
|
||||
return GetSCC(d)->GetRepresentative();
|
||||
}
|
||||
const SCC* GetSCC(const Descriptor* d) { return scc_analyzer_.GetSCC(d); }
|
||||
|
||||
bool IsDepWeak(const FileDescriptor* dep) const {
|
||||
if (weak_deps_.count(dep) != 0) {
|
||||
GOOGLE_CHECK(!options_.opensource_runtime);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::set<const FileDescriptor*> weak_deps_;
|
||||
std::vector<const SCC*> sccs_;
|
||||
|
||||
const FileDescriptor* file_;
|
||||
const Options options_;
|
||||
|
||||
MessageSCCAnalyzer scc_analyzer_;
|
||||
|
||||
std::map<std::string, std::string> variables_;
|
||||
|
||||
// Contains the post-order walk of all the messages (and child messages) in
|
||||
// this file. If you need a pre-order walk just reverse iterate.
|
||||
std::vector<std::unique_ptr<MessageGenerator>> message_generators_;
|
||||
std::vector<std::unique_ptr<EnumGenerator>> enum_generators_;
|
||||
std::vector<std::unique_ptr<ServiceGenerator>> service_generators_;
|
||||
std::vector<std::unique_ptr<ExtensionGenerator>> extension_generators_;
|
||||
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator);
|
||||
};
|
||||
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_CPP_FILE_H__
|
||||
219
ubuntu/google/protobuf/compiler/cpp/cpp_generator.cc
Normal file
219
ubuntu/google/protobuf/compiler/cpp/cpp_generator.cc
Normal file
@@ -0,0 +1,219 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// 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_generator.h>
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <google/protobuf/stubs/strutil.h>
|
||||
#include <google/protobuf/compiler/cpp/cpp_file.h>
|
||||
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
|
||||
#include <google/protobuf/descriptor.pb.h>
|
||||
#include <google/protobuf/io/printer.h>
|
||||
#include <google/protobuf/io/zero_copy_stream.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace cpp {
|
||||
|
||||
CppGenerator::CppGenerator() {}
|
||||
CppGenerator::~CppGenerator() {}
|
||||
|
||||
bool CppGenerator::Generate(const FileDescriptor* file,
|
||||
const std::string& parameter,
|
||||
GeneratorContext* generator_context,
|
||||
std::string* error) const {
|
||||
std::vector<std::pair<std::string, std::string> > options;
|
||||
ParseGeneratorParameter(parameter, &options);
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// parse generator options
|
||||
|
||||
// If the dllexport_decl option is passed to the compiler, we need to write
|
||||
// it in front of every symbol that should be exported if this .proto is
|
||||
// compiled into a Windows DLL. E.g., if the user invokes the protocol
|
||||
// compiler as:
|
||||
// protoc --cpp_out=dllexport_decl=FOO_EXPORT:outdir foo.proto
|
||||
// then we'll define classes like this:
|
||||
// class FOO_EXPORT Foo {
|
||||
// ...
|
||||
// }
|
||||
// FOO_EXPORT is a macro which should expand to __declspec(dllexport) or
|
||||
// __declspec(dllimport) depending on what is being compiled.
|
||||
//
|
||||
Options file_options;
|
||||
|
||||
file_options.opensource_runtime = opensource_runtime_;
|
||||
file_options.runtime_include_base = runtime_include_base_;
|
||||
|
||||
for (int i = 0; i < options.size(); i++) {
|
||||
if (options[i].first == "dllexport_decl") {
|
||||
file_options.dllexport_decl = options[i].second;
|
||||
} else if (options[i].first == "safe_boundary_check") {
|
||||
file_options.safe_boundary_check = true;
|
||||
} else if (options[i].first == "annotate_headers") {
|
||||
file_options.annotate_headers = true;
|
||||
} else if (options[i].first == "annotation_pragma_name") {
|
||||
file_options.annotation_pragma_name = options[i].second;
|
||||
} else if (options[i].first == "annotation_guard_name") {
|
||||
file_options.annotation_guard_name = options[i].second;
|
||||
} else if (options[i].first == "speed") {
|
||||
file_options.enforce_mode = EnforceOptimizeMode::kSpeed;
|
||||
} else if (options[i].first == "code_size") {
|
||||
file_options.enforce_mode = EnforceOptimizeMode::kCodeSize;
|
||||
} else if (options[i].first == "lite") {
|
||||
file_options.enforce_mode = EnforceOptimizeMode::kLiteRuntime;
|
||||
} else if (options[i].first == "lite_implicit_weak_fields") {
|
||||
file_options.enforce_mode = EnforceOptimizeMode::kLiteRuntime;
|
||||
file_options.lite_implicit_weak_fields = true;
|
||||
if (!options[i].second.empty()) {
|
||||
file_options.num_cc_files =
|
||||
strto32(options[i].second.c_str(), NULL, 10);
|
||||
}
|
||||
} else if (options[i].first == "table_driven_parsing") {
|
||||
file_options.table_driven_parsing = true;
|
||||
} else if (options[i].first == "table_driven_serialization") {
|
||||
file_options.table_driven_serialization = true;
|
||||
} else {
|
||||
*error = "Unknown generator option: " + options[i].first;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// The safe_boundary_check option controls behavior for Google-internal
|
||||
// protobuf APIs.
|
||||
if (file_options.safe_boundary_check && file_options.opensource_runtime) {
|
||||
*error =
|
||||
"The safe_boundary_check option is not supported outside of Google.";
|
||||
return false;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
|
||||
std::string basename = StripProto(file->name());
|
||||
|
||||
if (MaybeBootstrap(file_options, generator_context, file_options.bootstrap,
|
||||
&basename)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
FileGenerator file_generator(file, file_options);
|
||||
|
||||
// Generate header(s).
|
||||
if (file_options.proto_h) {
|
||||
std::unique_ptr<io::ZeroCopyOutputStream> output(
|
||||
generator_context->Open(basename + ".proto.h"));
|
||||
GeneratedCodeInfo annotations;
|
||||
io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector(
|
||||
&annotations);
|
||||
std::string info_path = basename + ".proto.h.meta";
|
||||
io::Printer printer(
|
||||
output.get(), '$',
|
||||
file_options.annotate_headers ? &annotation_collector : NULL);
|
||||
file_generator.GenerateProtoHeader(
|
||||
&printer, file_options.annotate_headers ? info_path : "");
|
||||
if (file_options.annotate_headers) {
|
||||
std::unique_ptr<io::ZeroCopyOutputStream> info_output(
|
||||
generator_context->Open(info_path));
|
||||
annotations.SerializeToZeroCopyStream(info_output.get());
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
std::unique_ptr<io::ZeroCopyOutputStream> output(
|
||||
generator_context->Open(basename + ".pb.h"));
|
||||
GeneratedCodeInfo annotations;
|
||||
io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector(
|
||||
&annotations);
|
||||
std::string info_path = basename + ".pb.h.meta";
|
||||
io::Printer printer(
|
||||
output.get(), '$',
|
||||
file_options.annotate_headers ? &annotation_collector : NULL);
|
||||
file_generator.GeneratePBHeader(
|
||||
&printer, file_options.annotate_headers ? info_path : "");
|
||||
if (file_options.annotate_headers) {
|
||||
std::unique_ptr<io::ZeroCopyOutputStream> info_output(
|
||||
generator_context->Open(info_path));
|
||||
annotations.SerializeToZeroCopyStream(info_output.get());
|
||||
}
|
||||
}
|
||||
|
||||
// Generate cc file(s).
|
||||
if (UsingImplicitWeakFields(file, file_options)) {
|
||||
{
|
||||
// This is the global .cc file, containing
|
||||
// enum/services/tables/reflection
|
||||
std::unique_ptr<io::ZeroCopyOutputStream> output(
|
||||
generator_context->Open(basename + ".pb.cc"));
|
||||
io::Printer printer(output.get(), '$');
|
||||
file_generator.GenerateGlobalSource(&printer);
|
||||
}
|
||||
|
||||
int num_cc_files = file_generator.NumMessages();
|
||||
|
||||
// If we're using implicit weak fields then we allow the user to
|
||||
// optionally specify how many files to generate, not counting the global
|
||||
// pb.cc file. If we have more files than messages, then some files will
|
||||
// be generated as empty placeholders.
|
||||
if (file_options.num_cc_files > 0) {
|
||||
GOOGLE_CHECK_LE(file_generator.NumMessages(), file_options.num_cc_files)
|
||||
<< "There must be at least as many numbered .cc files as messages.";
|
||||
num_cc_files = file_options.num_cc_files;
|
||||
}
|
||||
for (int i = 0; i < num_cc_files; i++) {
|
||||
std::unique_ptr<io::ZeroCopyOutputStream> output(
|
||||
generator_context->Open(StrCat(basename, ".out/", i, ".cc")));
|
||||
io::Printer printer(output.get(), '$');
|
||||
if (i < file_generator.NumMessages()) {
|
||||
file_generator.GenerateSourceForMessage(i, &printer);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
std::unique_ptr<io::ZeroCopyOutputStream> output(
|
||||
generator_context->Open(basename + ".pb.cc"));
|
||||
io::Printer printer(output.get(), '$');
|
||||
file_generator.GenerateSource(&printer);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
106
ubuntu/google/protobuf/compiler/cpp/cpp_generator.h
Normal file
106
ubuntu/google/protobuf/compiler/cpp/cpp_generator.h
Normal file
@@ -0,0 +1,106 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Author: kenton@google.com (Kenton Varda)
|
||||
// Based on original Protocol Buffers design by
|
||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||
//
|
||||
// Generates C++ code for a given .proto file.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__
|
||||
#define GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__
|
||||
|
||||
#include <string>
|
||||
#include <google/protobuf/compiler/code_generator.h>
|
||||
|
||||
#include <google/protobuf/port_def.inc>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace cpp {
|
||||
|
||||
// CodeGenerator implementation which generates a C++ source file and
|
||||
// header. If you create your own protocol compiler binary and you want
|
||||
// it to support C++ output, you can do so by registering an instance of this
|
||||
// CodeGenerator with the CommandLineInterface in your main() function.
|
||||
class PROTOC_EXPORT CppGenerator : public CodeGenerator {
|
||||
public:
|
||||
CppGenerator();
|
||||
~CppGenerator();
|
||||
|
||||
enum class Runtime {
|
||||
kGoogle3, // Use the internal google3 runtime.
|
||||
kOpensource, // Use the open-source runtime.
|
||||
|
||||
// Use the open-source runtime with google3 #include paths. We make these
|
||||
// absolute to avoid ambiguity, so the runtime will be #included like:
|
||||
// #include "third_party/protobuf/.../google/protobuf/message.h"
|
||||
kOpensourceGoogle3
|
||||
};
|
||||
|
||||
void set_opensource_runtime(bool opensource) {
|
||||
opensource_runtime_ = opensource;
|
||||
}
|
||||
|
||||
// If set to a non-empty string, generated code will do:
|
||||
// #include "<BASE>/google/protobuf/message.h"
|
||||
// instead of:
|
||||
// #include <google/protobuf/message.h>
|
||||
// This has no effect if opensource_runtime = false.
|
||||
void set_runtime_include_base(const std::string& base) {
|
||||
runtime_include_base_ = base;
|
||||
}
|
||||
|
||||
// implements CodeGenerator ----------------------------------------
|
||||
bool Generate(const FileDescriptor* file, const std::string& parameter,
|
||||
GeneratorContext* generator_context,
|
||||
std::string* error) const override;
|
||||
|
||||
uint64_t GetSupportedFeatures() const override {
|
||||
// We don't fully support this yet, but this is needed to unblock the tests,
|
||||
// and we will have full support before the experimental flag is removed.
|
||||
return FEATURE_PROTO3_OPTIONAL;
|
||||
}
|
||||
|
||||
private:
|
||||
bool opensource_runtime_ = true;
|
||||
std::string runtime_include_base_;
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CppGenerator);
|
||||
};
|
||||
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#include <google/protobuf/port_undef.inc>
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_CPP_GENERATOR_H__
|
||||
1994
ubuntu/google/protobuf/compiler/cpp/cpp_helpers.cc
Normal file
1994
ubuntu/google/protobuf/compiler/cpp/cpp_helpers.cc
Normal file
File diff suppressed because it is too large
Load Diff
890
ubuntu/google/protobuf/compiler/cpp/cpp_helpers.h
Normal file
890
ubuntu/google/protobuf/compiler/cpp/cpp_helpers.h
Normal file
@@ -0,0 +1,890 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Author: kenton@google.com (Kenton Varda)
|
||||
// Based on original Protocol Buffers design by
|
||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__
|
||||
#define GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include <google/protobuf/compiler/cpp/cpp_options.h>
|
||||
#include <google/protobuf/compiler/scc.h>
|
||||
#include <google/protobuf/compiler/code_generator.h>
|
||||
#include <google/protobuf/descriptor.pb.h>
|
||||
#include <google/protobuf/io/printer.h>
|
||||
#include <google/protobuf/descriptor.h>
|
||||
#include <google/protobuf/port.h>
|
||||
#include <google/protobuf/stubs/strutil.h>
|
||||
|
||||
// Must be included last.
|
||||
#include <google/protobuf/port_def.inc>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace cpp {
|
||||
|
||||
inline std::string ProtobufNamespace(const Options& options) {
|
||||
return "PROTOBUF_NAMESPACE_ID";
|
||||
}
|
||||
|
||||
inline std::string MacroPrefix(const Options& options) {
|
||||
return options.opensource_runtime ? "GOOGLE_PROTOBUF" : "GOOGLE_PROTOBUF";
|
||||
}
|
||||
|
||||
inline std::string DeprecatedAttribute(const Options& options,
|
||||
const FieldDescriptor* d) {
|
||||
return d->options().deprecated() ? "PROTOBUF_DEPRECATED " : "";
|
||||
}
|
||||
|
||||
inline std::string DeprecatedAttribute(const Options& options,
|
||||
const EnumValueDescriptor* d) {
|
||||
return d->options().deprecated() ? "PROTOBUF_DEPRECATED_ENUM " : "";
|
||||
}
|
||||
|
||||
// Commonly-used separator comments. Thick is a line of '=', thin is a line
|
||||
// of '-'.
|
||||
extern const char kThickSeparator[];
|
||||
extern const char kThinSeparator[];
|
||||
|
||||
void SetCommonVars(const Options& options,
|
||||
std::map<std::string, std::string>* variables);
|
||||
|
||||
void SetUnknkownFieldsVariable(const Descriptor* descriptor,
|
||||
const Options& options,
|
||||
std::map<std::string, std::string>* variables);
|
||||
|
||||
bool GetBootstrapBasename(const Options& options, const std::string& basename,
|
||||
std::string* bootstrap_basename);
|
||||
bool MaybeBootstrap(const Options& options, GeneratorContext* generator_context,
|
||||
bool bootstrap_flag, std::string* basename);
|
||||
bool IsBootstrapProto(const Options& options, const FileDescriptor* file);
|
||||
|
||||
// Name space of the proto file. This namespace is such that the string
|
||||
// "<namespace>::some_name" is the correct fully qualified namespace.
|
||||
// This means if the package is empty the namespace is "", and otherwise
|
||||
// the namespace is "::foo::bar::...::baz" without trailing semi-colons.
|
||||
std::string Namespace(const FileDescriptor* d, const Options& options);
|
||||
std::string Namespace(const Descriptor* d, const Options& options);
|
||||
std::string Namespace(const FieldDescriptor* d, const Options& options);
|
||||
std::string Namespace(const EnumDescriptor* d, const Options& options);
|
||||
|
||||
// Returns true if it's safe to reset "field" to zero.
|
||||
bool CanInitializeByZeroing(const FieldDescriptor* field);
|
||||
|
||||
std::string ClassName(const Descriptor* descriptor);
|
||||
std::string ClassName(const EnumDescriptor* enum_descriptor);
|
||||
|
||||
std::string QualifiedClassName(const Descriptor* d, const Options& options);
|
||||
std::string QualifiedClassName(const EnumDescriptor* d, const Options& options);
|
||||
|
||||
std::string QualifiedClassName(const Descriptor* d);
|
||||
std::string QualifiedClassName(const EnumDescriptor* d);
|
||||
|
||||
// DEPRECATED just use ClassName or QualifiedClassName, a boolean is very
|
||||
// unreadable at the callsite.
|
||||
// Returns the non-nested type name for the given type. If "qualified" is
|
||||
// true, prefix the type with the full namespace. For example, if you had:
|
||||
// package foo.bar;
|
||||
// message Baz { message Qux {} }
|
||||
// Then the qualified ClassName for Qux would be:
|
||||
// ::foo::bar::Baz_Qux
|
||||
// While the non-qualified version would be:
|
||||
// Baz_Qux
|
||||
inline std::string ClassName(const Descriptor* descriptor, bool qualified) {
|
||||
return qualified ? QualifiedClassName(descriptor, Options())
|
||||
: ClassName(descriptor);
|
||||
}
|
||||
|
||||
inline std::string ClassName(const EnumDescriptor* descriptor, bool qualified) {
|
||||
return qualified ? QualifiedClassName(descriptor, Options())
|
||||
: ClassName(descriptor);
|
||||
}
|
||||
|
||||
std::string QualifiedExtensionName(const FieldDescriptor* d,
|
||||
const Options& options);
|
||||
std::string QualifiedExtensionName(const FieldDescriptor* d);
|
||||
|
||||
// Type name of default instance.
|
||||
std::string DefaultInstanceType(const Descriptor* descriptor,
|
||||
const Options& options);
|
||||
|
||||
// Non-qualified name of the default_instance of this message.
|
||||
std::string DefaultInstanceName(const Descriptor* descriptor,
|
||||
const Options& options);
|
||||
|
||||
// Non-qualified name of the default instance pointer. This is used only for
|
||||
// implicit weak fields, where we need an extra indirection.
|
||||
std::string DefaultInstancePtr(const Descriptor* descriptor,
|
||||
const Options& options);
|
||||
|
||||
// Fully qualified name of the default_instance of this message.
|
||||
std::string QualifiedDefaultInstanceName(const Descriptor* descriptor,
|
||||
const Options& options);
|
||||
|
||||
// Fully qualified name of the default instance pointer.
|
||||
std::string QualifiedDefaultInstancePtr(const Descriptor* descriptor,
|
||||
const Options& options);
|
||||
|
||||
// DescriptorTable variable name.
|
||||
std::string DescriptorTableName(const FileDescriptor* file,
|
||||
const Options& options);
|
||||
|
||||
// When declaring symbol externs from another file, this macro will supply the
|
||||
// dllexport needed for the target file, if any.
|
||||
std::string FileDllExport(const FileDescriptor* file, const Options& options);
|
||||
|
||||
// Name of the base class: google::protobuf::Message or google::protobuf::MessageLite.
|
||||
std::string SuperClassName(const Descriptor* descriptor,
|
||||
const Options& options);
|
||||
|
||||
// Adds an underscore if necessary to prevent conflicting with a keyword.
|
||||
std::string ResolveKeyword(const std::string& name);
|
||||
|
||||
// Get the (unqualified) name that should be used for this field in C++ code.
|
||||
// The name is coerced to lower-case to emulate proto1 behavior. People
|
||||
// should be using lowercase-with-underscores style for proto field names
|
||||
// anyway, so normally this just returns field->name().
|
||||
std::string FieldName(const FieldDescriptor* field);
|
||||
|
||||
// Get the sanitized name that should be used for the given enum in C++ code.
|
||||
std::string EnumValueName(const EnumValueDescriptor* enum_value);
|
||||
|
||||
// Returns an estimate of the compiler's alignment for the field. This
|
||||
// can't guarantee to be correct because the generated code could be compiled on
|
||||
// different systems with different alignment rules. The estimates below assume
|
||||
// 64-bit pointers.
|
||||
int EstimateAlignmentSize(const FieldDescriptor* field);
|
||||
|
||||
// Get the unqualified name that should be used for a field's field
|
||||
// number constant.
|
||||
std::string FieldConstantName(const FieldDescriptor* field);
|
||||
|
||||
// Returns the scope where the field was defined (for extensions, this is
|
||||
// different from the message type to which the field applies).
|
||||
inline const Descriptor* FieldScope(const FieldDescriptor* field) {
|
||||
return field->is_extension() ? field->extension_scope()
|
||||
: field->containing_type();
|
||||
}
|
||||
|
||||
// Returns the fully-qualified type name field->message_type(). Usually this
|
||||
// is just ClassName(field->message_type(), true);
|
||||
std::string FieldMessageTypeName(const FieldDescriptor* field,
|
||||
const Options& options);
|
||||
|
||||
// Strips ".proto" or ".protodevel" from the end of a filename.
|
||||
PROTOC_EXPORT std::string StripProto(const std::string& filename);
|
||||
|
||||
// Get the C++ type name for a primitive type (e.g. "double", "::google::protobuf::int32", etc.).
|
||||
const char* PrimitiveTypeName(FieldDescriptor::CppType type);
|
||||
std::string PrimitiveTypeName(const Options& options,
|
||||
FieldDescriptor::CppType type);
|
||||
|
||||
// Get the declared type name in CamelCase format, as is used e.g. for the
|
||||
// methods of WireFormat. For example, TYPE_INT32 becomes "Int32".
|
||||
const char* DeclaredTypeMethodName(FieldDescriptor::Type type);
|
||||
|
||||
// Return the code that evaluates to the number when compiled.
|
||||
std::string Int32ToString(int number);
|
||||
|
||||
// Return the code that evaluates to the number when compiled.
|
||||
std::string Int64ToString(const Options& options, int64 number);
|
||||
|
||||
// Get code that evaluates to the field's default value.
|
||||
std::string DefaultValue(const Options& options, const FieldDescriptor* field);
|
||||
|
||||
// Compatibility function for callers outside proto2.
|
||||
std::string DefaultValue(const FieldDescriptor* field);
|
||||
|
||||
// Convert a file name into a valid identifier.
|
||||
std::string FilenameIdentifier(const std::string& filename);
|
||||
|
||||
// For each .proto file generates a unique name. To prevent collisions of
|
||||
// symbols in the global namespace
|
||||
std::string UniqueName(const std::string& name, const std::string& filename,
|
||||
const Options& options);
|
||||
inline std::string UniqueName(const std::string& name, const FileDescriptor* d,
|
||||
const Options& options) {
|
||||
return UniqueName(name, d->name(), options);
|
||||
}
|
||||
inline std::string UniqueName(const std::string& name, const Descriptor* d,
|
||||
const Options& options) {
|
||||
return UniqueName(name, d->file(), options);
|
||||
}
|
||||
inline std::string UniqueName(const std::string& name, const EnumDescriptor* d,
|
||||
const Options& options) {
|
||||
return UniqueName(name, d->file(), options);
|
||||
}
|
||||
inline std::string UniqueName(const std::string& name,
|
||||
const ServiceDescriptor* d,
|
||||
const Options& options) {
|
||||
return UniqueName(name, d->file(), options);
|
||||
}
|
||||
|
||||
// Versions for call sites that only support the internal runtime (like proto1
|
||||
// support).
|
||||
inline Options InternalRuntimeOptions() {
|
||||
Options options;
|
||||
options.opensource_runtime = false;
|
||||
return options;
|
||||
}
|
||||
inline std::string UniqueName(const std::string& name,
|
||||
const std::string& filename) {
|
||||
return UniqueName(name, filename, InternalRuntimeOptions());
|
||||
}
|
||||
inline std::string UniqueName(const std::string& name,
|
||||
const FileDescriptor* d) {
|
||||
return UniqueName(name, d->name(), InternalRuntimeOptions());
|
||||
}
|
||||
inline std::string UniqueName(const std::string& name, const Descriptor* d) {
|
||||
return UniqueName(name, d->file(), InternalRuntimeOptions());
|
||||
}
|
||||
inline std::string UniqueName(const std::string& name,
|
||||
const EnumDescriptor* d) {
|
||||
return UniqueName(name, d->file(), InternalRuntimeOptions());
|
||||
}
|
||||
inline std::string UniqueName(const std::string& name,
|
||||
const ServiceDescriptor* d) {
|
||||
return UniqueName(name, d->file(), InternalRuntimeOptions());
|
||||
}
|
||||
|
||||
// Return the qualified C++ name for a file level symbol.
|
||||
std::string QualifiedFileLevelSymbol(const FileDescriptor* file,
|
||||
const std::string& name,
|
||||
const Options& options);
|
||||
|
||||
// Escape C++ trigraphs by escaping question marks to \?
|
||||
std::string EscapeTrigraphs(const std::string& to_escape);
|
||||
|
||||
// Escaped function name to eliminate naming conflict.
|
||||
std::string SafeFunctionName(const Descriptor* descriptor,
|
||||
const FieldDescriptor* field,
|
||||
const std::string& prefix);
|
||||
|
||||
// Returns true if generated messages have public unknown fields accessors
|
||||
inline bool PublicUnknownFieldsAccessors(const Descriptor* message) {
|
||||
return message->file()->syntax() != FileDescriptor::SYNTAX_PROTO3;
|
||||
}
|
||||
|
||||
// Returns the optimize mode for <file>, respecting <options.enforce_lite>.
|
||||
FileOptions_OptimizeMode GetOptimizeFor(const FileDescriptor* file,
|
||||
const Options& options);
|
||||
|
||||
// Determines whether unknown fields will be stored in an UnknownFieldSet or
|
||||
// a string.
|
||||
inline bool UseUnknownFieldSet(const FileDescriptor* file,
|
||||
const Options& options) {
|
||||
return GetOptimizeFor(file, options) != FileOptions::LITE_RUNTIME;
|
||||
}
|
||||
|
||||
inline bool IsWeak(const FieldDescriptor* field, const Options& options) {
|
||||
if (field->options().weak()) {
|
||||
GOOGLE_CHECK(!options.opensource_runtime);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// For a string field, returns the effective ctype. If the actual ctype is
|
||||
// not supported, returns the default of STRING.
|
||||
FieldOptions::CType EffectiveStringCType(const FieldDescriptor* field,
|
||||
const Options& options);
|
||||
|
||||
inline bool IsCord(const FieldDescriptor* field, const Options& options) {
|
||||
return field->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
|
||||
EffectiveStringCType(field, options) == FieldOptions::CORD;
|
||||
}
|
||||
|
||||
inline bool IsStringPiece(const FieldDescriptor* field,
|
||||
const Options& options) {
|
||||
return field->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
|
||||
EffectiveStringCType(field, options) == FieldOptions::STRING_PIECE;
|
||||
}
|
||||
|
||||
// Does the given FileDescriptor use lazy fields?
|
||||
bool HasLazyFields(const FileDescriptor* file, const Options& options);
|
||||
|
||||
// Is the given field a supported lazy field?
|
||||
inline bool IsLazy(const FieldDescriptor* field, const Options& options) {
|
||||
return field->options().lazy() && !field->is_repeated() &&
|
||||
field->type() == FieldDescriptor::TYPE_MESSAGE &&
|
||||
GetOptimizeFor(field->file(), options) != FileOptions::LITE_RUNTIME &&
|
||||
!options.opensource_runtime;
|
||||
}
|
||||
|
||||
inline bool IsFieldUsed(const FieldDescriptor* field, const Options& options) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns true if "field" is stripped.
|
||||
inline bool IsFieldStripped(const FieldDescriptor* /*field*/,
|
||||
const Options& /*options*/) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Does the file contain any definitions that need extension_set.h?
|
||||
bool HasExtensionsOrExtendableMessage(const FileDescriptor* file);
|
||||
|
||||
// Does the file have any repeated fields, necessitating the file to include
|
||||
// repeated_field.h? This does not include repeated extensions, since those are
|
||||
// all stored internally in an ExtensionSet, not a separate RepeatedField*.
|
||||
bool HasRepeatedFields(const FileDescriptor* file);
|
||||
|
||||
// Does the file have any string/bytes fields with ctype=STRING_PIECE? This
|
||||
// does not include extensions, since ctype is ignored for extensions.
|
||||
bool HasStringPieceFields(const FileDescriptor* file, const Options& options);
|
||||
|
||||
// Does the file have any string/bytes fields with ctype=CORD? This does not
|
||||
// include extensions, since ctype is ignored for extensions.
|
||||
bool HasCordFields(const FileDescriptor* file, const Options& options);
|
||||
|
||||
// Does the file have any map fields, necessitating the file to include
|
||||
// map_field_inl.h and map.h.
|
||||
bool HasMapFields(const FileDescriptor* file);
|
||||
|
||||
// Does this file have any enum type definitions?
|
||||
bool HasEnumDefinitions(const FileDescriptor* file);
|
||||
|
||||
// Does this file have generated parsing, serialization, and other
|
||||
// standard methods for which reflection-based fallback implementations exist?
|
||||
inline bool HasGeneratedMethods(const FileDescriptor* file,
|
||||
const Options& options) {
|
||||
return GetOptimizeFor(file, options) != FileOptions::CODE_SIZE;
|
||||
}
|
||||
|
||||
// Do message classes in this file have descriptor and reflection methods?
|
||||
inline bool HasDescriptorMethods(const FileDescriptor* file,
|
||||
const Options& options) {
|
||||
return GetOptimizeFor(file, options) != FileOptions::LITE_RUNTIME;
|
||||
}
|
||||
|
||||
// Should we generate generic services for this file?
|
||||
inline bool HasGenericServices(const FileDescriptor* file,
|
||||
const Options& options) {
|
||||
return file->service_count() > 0 &&
|
||||
GetOptimizeFor(file, options) != FileOptions::LITE_RUNTIME &&
|
||||
file->options().cc_generic_services();
|
||||
}
|
||||
|
||||
inline bool IsProto2MessageSet(const Descriptor* descriptor,
|
||||
const Options& options) {
|
||||
return !options.opensource_runtime &&
|
||||
options.enforce_mode != EnforceOptimizeMode::kLiteRuntime &&
|
||||
!options.lite_implicit_weak_fields &&
|
||||
descriptor->options().message_set_wire_format() &&
|
||||
descriptor->full_name() == "google.protobuf.bridge.MessageSet";
|
||||
}
|
||||
|
||||
inline bool IsMapEntryMessage(const Descriptor* descriptor) {
|
||||
return descriptor->options().map_entry();
|
||||
}
|
||||
|
||||
// Returns true if the field's CPPTYPE is string or message.
|
||||
bool IsStringOrMessage(const FieldDescriptor* field);
|
||||
|
||||
std::string UnderscoresToCamelCase(const std::string& input,
|
||||
bool cap_next_letter);
|
||||
|
||||
inline bool HasFieldPresence(const FileDescriptor* file) {
|
||||
return file->syntax() != FileDescriptor::SYNTAX_PROTO3;
|
||||
}
|
||||
|
||||
inline bool HasHasbit(const FieldDescriptor* field) {
|
||||
// This predicate includes proto3 message fields only if they have "optional".
|
||||
// Foo submsg1 = 1; // HasHasbit() == false
|
||||
// optional Foo submsg2 = 2; // HasHasbit() == true
|
||||
// This is slightly odd, as adding "optional" to a singular proto3 field does
|
||||
// not change the semantics or API. However whenever any field in a message
|
||||
// has a hasbit, it forces reflection to include hasbit offsets for *all*
|
||||
// fields, even if almost all of them are set to -1 (no hasbit). So to avoid
|
||||
// causing a sudden size regression for ~all proto3 messages, we give proto3
|
||||
// message fields a hasbit only if "optional" is present. If the user is
|
||||
// explicitly writing "optional", it is likely they are writing it on
|
||||
// primitive fields also.
|
||||
return (field->has_optional_keyword() || field->is_required()) &&
|
||||
!field->options().weak();
|
||||
}
|
||||
|
||||
// Returns true if 'enum' semantics are such that unknown values are preserved
|
||||
// in the enum field itself, rather than going to the UnknownFieldSet.
|
||||
inline bool HasPreservingUnknownEnumSemantics(const FieldDescriptor* field) {
|
||||
return field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3;
|
||||
}
|
||||
|
||||
inline bool IsCrossFileMessage(const FieldDescriptor* field) {
|
||||
return field->type() == FieldDescriptor::TYPE_MESSAGE &&
|
||||
field->message_type()->file() != field->file();
|
||||
}
|
||||
|
||||
inline std::string MakeDefaultName(const FieldDescriptor* field) {
|
||||
return "_i_give_permission_to_break_this_code_default_" + FieldName(field) +
|
||||
"_";
|
||||
}
|
||||
|
||||
bool IsAnyMessage(const FileDescriptor* descriptor, const Options& options);
|
||||
bool IsAnyMessage(const Descriptor* descriptor, const Options& options);
|
||||
|
||||
bool IsWellKnownMessage(const FileDescriptor* descriptor);
|
||||
|
||||
inline std::string IncludeGuard(const FileDescriptor* file, bool pb_h,
|
||||
const Options& options) {
|
||||
// If we are generating a .pb.h file and the proto_h option is enabled, then
|
||||
// the .pb.h gets an extra suffix.
|
||||
std::string filename_identifier = FilenameIdentifier(
|
||||
file->name() + (pb_h && options.proto_h ? ".pb.h" : ""));
|
||||
|
||||
if (IsWellKnownMessage(file)) {
|
||||
// For well-known messages we need third_party/protobuf and net/proto2 to
|
||||
// have distinct include guards, because some source files include both and
|
||||
// both need to be defined (the third_party copies will be in the
|
||||
// google::protobuf_opensource namespace).
|
||||
return MacroPrefix(options) + "_INCLUDED_" + filename_identifier;
|
||||
} else {
|
||||
// Ideally this case would use distinct include guards for opensource and
|
||||
// google3 protos also. (The behavior of "first #included wins" is not
|
||||
// ideal). But unfortunately some legacy code includes both and depends on
|
||||
// the identical include guards to avoid compile errors.
|
||||
//
|
||||
// We should clean this up so that this case can be removed.
|
||||
return "GOOGLE_PROTOBUF_INCLUDED_" + filename_identifier;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the OptimizeMode for this file, furthermore it updates a status
|
||||
// bool if has_opt_codesize_extension is non-null. If this status bool is true
|
||||
// it means this file contains an extension that itself is defined as
|
||||
// optimized_for = CODE_SIZE.
|
||||
FileOptions_OptimizeMode GetOptimizeFor(const FileDescriptor* file,
|
||||
const Options& options,
|
||||
bool* has_opt_codesize_extension);
|
||||
inline FileOptions_OptimizeMode GetOptimizeFor(const FileDescriptor* file,
|
||||
const Options& options) {
|
||||
return GetOptimizeFor(file, options, nullptr);
|
||||
}
|
||||
inline bool NeedsEagerDescriptorAssignment(const FileDescriptor* file,
|
||||
const Options& options) {
|
||||
bool has_opt_codesize_extension;
|
||||
if (GetOptimizeFor(file, options, &has_opt_codesize_extension) ==
|
||||
FileOptions::CODE_SIZE &&
|
||||
has_opt_codesize_extension) {
|
||||
// If this filedescriptor contains an extension from another file which
|
||||
// is optimized_for = CODE_SIZE. We need to be careful in the ordering so
|
||||
// we eagerly build the descriptors in the dependencies before building
|
||||
// the descriptors of this file.
|
||||
return true;
|
||||
} else {
|
||||
// If we have a generated code based parser we never need eager
|
||||
// initialization of descriptors of our deps.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// This orders the messages in a .pb.cc as it's outputted by file.cc
|
||||
void FlattenMessagesInFile(const FileDescriptor* file,
|
||||
std::vector<const Descriptor*>* result);
|
||||
inline std::vector<const Descriptor*> FlattenMessagesInFile(
|
||||
const FileDescriptor* file) {
|
||||
std::vector<const Descriptor*> result;
|
||||
FlattenMessagesInFile(file, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool HasWeakFields(const Descriptor* desc, const Options& options);
|
||||
bool HasWeakFields(const FileDescriptor* desc, const Options& options);
|
||||
|
||||
// Returns true if the "required" restriction check should be ignored for the
|
||||
// given field.
|
||||
inline static bool ShouldIgnoreRequiredFieldCheck(const FieldDescriptor* field,
|
||||
const Options& options) {
|
||||
// Do not check "required" for lazy fields.
|
||||
return IsLazy(field, options);
|
||||
}
|
||||
|
||||
struct MessageAnalysis {
|
||||
bool is_recursive;
|
||||
bool contains_cord;
|
||||
bool contains_extension;
|
||||
bool contains_required;
|
||||
bool constructor_requires_initialization;
|
||||
};
|
||||
|
||||
// This class is used in FileGenerator, to ensure linear instead of
|
||||
// quadratic performance, if we do this per message we would get O(V*(V+E)).
|
||||
// Logically this is just only used in message.cc, but in the header for
|
||||
// FileGenerator to help share it.
|
||||
class PROTOC_EXPORT MessageSCCAnalyzer {
|
||||
public:
|
||||
explicit MessageSCCAnalyzer(const Options& options) : options_(options) {}
|
||||
|
||||
MessageAnalysis GetSCCAnalysis(const SCC* scc);
|
||||
|
||||
bool HasRequiredFields(const Descriptor* descriptor) {
|
||||
MessageAnalysis result = GetSCCAnalysis(GetSCC(descriptor));
|
||||
return result.contains_required || result.contains_extension;
|
||||
}
|
||||
const SCC* GetSCC(const Descriptor* descriptor) {
|
||||
return analyzer_.GetSCC(descriptor);
|
||||
}
|
||||
|
||||
private:
|
||||
struct DepsGenerator {
|
||||
std::vector<const Descriptor*> operator()(const Descriptor* desc) const {
|
||||
std::vector<const Descriptor*> deps;
|
||||
for (int i = 0; i < desc->field_count(); i++) {
|
||||
if (desc->field(i)->message_type()) {
|
||||
deps.push_back(desc->field(i)->message_type());
|
||||
}
|
||||
}
|
||||
return deps;
|
||||
}
|
||||
};
|
||||
SCCAnalyzer<DepsGenerator> analyzer_;
|
||||
Options options_;
|
||||
std::map<const SCC*, MessageAnalysis> analysis_cache_;
|
||||
};
|
||||
|
||||
inline std::string SccInfoSymbol(const SCC* scc, const Options& options) {
|
||||
return UniqueName("scc_info_" + ClassName(scc->GetRepresentative()),
|
||||
scc->GetRepresentative(), options);
|
||||
}
|
||||
|
||||
inline std::string SccInfoPtrSymbol(const SCC* scc, const Options& options) {
|
||||
return UniqueName("scc_info_ptr_" + ClassName(scc->GetRepresentative()),
|
||||
scc->GetRepresentative(), options);
|
||||
}
|
||||
|
||||
void ListAllFields(const Descriptor* d,
|
||||
std::vector<const FieldDescriptor*>* fields);
|
||||
void ListAllFields(const FileDescriptor* d,
|
||||
std::vector<const FieldDescriptor*>* fields);
|
||||
|
||||
template <class T>
|
||||
void ForEachField(const Descriptor* d, T&& func) {
|
||||
for (int i = 0; i < d->nested_type_count(); i++) {
|
||||
ForEachField(d->nested_type(i), std::forward<T&&>(func));
|
||||
}
|
||||
for (int i = 0; i < d->extension_count(); i++) {
|
||||
func(d->extension(i));
|
||||
}
|
||||
for (int i = 0; i < d->field_count(); i++) {
|
||||
func(d->field(i));
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void ForEachField(const FileDescriptor* d, T&& func) {
|
||||
for (int i = 0; i < d->message_type_count(); i++) {
|
||||
ForEachField(d->message_type(i), std::forward<T&&>(func));
|
||||
}
|
||||
for (int i = 0; i < d->extension_count(); i++) {
|
||||
func(d->extension(i));
|
||||
}
|
||||
}
|
||||
|
||||
void ListAllTypesForServices(const FileDescriptor* fd,
|
||||
std::vector<const Descriptor*>* types);
|
||||
|
||||
// Indicates whether we should use implicit weak fields for this file.
|
||||
bool UsingImplicitWeakFields(const FileDescriptor* file,
|
||||
const Options& options);
|
||||
|
||||
// Indicates whether to treat this field as implicitly weak.
|
||||
bool IsImplicitWeakField(const FieldDescriptor* field, const Options& options,
|
||||
MessageSCCAnalyzer* scc_analyzer);
|
||||
|
||||
// Formatter is a functor class which acts as a closure around printer and
|
||||
// the variable map. It's much like printer->Print except it supports both named
|
||||
// variables that are substituted using a key value map and direct arguments. In
|
||||
// the format string $1$, $2$, etc... are substituted for the first, second, ...
|
||||
// direct argument respectively in the format call, it accepts both strings and
|
||||
// integers. The implementation verifies all arguments are used and are "first"
|
||||
// used in order of appearance in the argument list. For example,
|
||||
//
|
||||
// Format("return array[$1$];", 3) -> "return array[3];"
|
||||
// Format("array[$2$] = $1$;", "Bla", 3) -> FATAL error (wrong order)
|
||||
// Format("array[$1$] = $2$;", 3, "Bla") -> "array[3] = Bla;"
|
||||
//
|
||||
// The arguments can be used more than once like
|
||||
//
|
||||
// Format("array[$1$] = $2$; // Index = $1$", 3, "Bla") ->
|
||||
// "array[3] = Bla; // Index = 3"
|
||||
//
|
||||
// If you use more arguments use the following style to help the reader,
|
||||
//
|
||||
// Format("int $1$() {\n"
|
||||
// " array[$2$] = $3$;\n"
|
||||
// " return $4$;"
|
||||
// "}\n",
|
||||
// funname, // 1
|
||||
// idx, // 2
|
||||
// varname, // 3
|
||||
// retval); // 4
|
||||
//
|
||||
// but consider using named variables. Named variables like $foo$, with some
|
||||
// identifier foo, are looked up in the map. One additional feature is that
|
||||
// spaces are accepted between the '$' delimiters, $ foo$ will
|
||||
// substiture to " bar" if foo stands for "bar", but in case it's empty
|
||||
// will substitute to "". Hence, for example,
|
||||
//
|
||||
// Format(vars, "$dllexport $void fun();") -> "void fun();"
|
||||
// "__declspec(export) void fun();"
|
||||
//
|
||||
// which is convenient to prevent double, leading or trailing spaces.
|
||||
class PROTOC_EXPORT Formatter {
|
||||
public:
|
||||
explicit Formatter(io::Printer* printer) : printer_(printer) {}
|
||||
Formatter(io::Printer* printer,
|
||||
const std::map<std::string, std::string>& vars)
|
||||
: printer_(printer), vars_(vars) {}
|
||||
|
||||
template <typename T>
|
||||
void Set(const std::string& key, const T& value) {
|
||||
vars_[key] = ToString(value);
|
||||
}
|
||||
|
||||
void AddMap(const std::map<std::string, std::string>& vars) {
|
||||
for (const auto& keyval : vars) vars_[keyval.first] = keyval.second;
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void operator()(const char* format, const Args&... args) const {
|
||||
printer_->FormatInternal({ToString(args)...}, vars_, format);
|
||||
}
|
||||
|
||||
void Indent() const { printer_->Indent(); }
|
||||
void Outdent() const { printer_->Outdent(); }
|
||||
io::Printer* printer() const { return printer_; }
|
||||
|
||||
class PROTOC_EXPORT SaveState {
|
||||
public:
|
||||
explicit SaveState(Formatter* format)
|
||||
: format_(format), vars_(format->vars_) {}
|
||||
~SaveState() { format_->vars_.swap(vars_); }
|
||||
|
||||
private:
|
||||
Formatter* format_;
|
||||
std::map<std::string, std::string> vars_;
|
||||
};
|
||||
|
||||
private:
|
||||
io::Printer* printer_;
|
||||
std::map<std::string, std::string> vars_;
|
||||
|
||||
// Convenience overloads to accept different types as arguments.
|
||||
static std::string ToString(const std::string& s) { return s; }
|
||||
template <typename I, typename = typename std::enable_if<
|
||||
std::is_integral<I>::value>::type>
|
||||
static std::string ToString(I x) {
|
||||
return StrCat(x);
|
||||
}
|
||||
static std::string ToString(strings::Hex x) { return StrCat(x); }
|
||||
static std::string ToString(const FieldDescriptor* d) { return Payload(d); }
|
||||
static std::string ToString(const Descriptor* d) { return Payload(d); }
|
||||
static std::string ToString(const EnumDescriptor* d) { return Payload(d); }
|
||||
static std::string ToString(const EnumValueDescriptor* d) {
|
||||
return Payload(d);
|
||||
}
|
||||
static std::string ToString(const OneofDescriptor* d) { return Payload(d); }
|
||||
|
||||
template <typename Descriptor>
|
||||
static std::string Payload(const Descriptor* descriptor) {
|
||||
std::vector<int> path;
|
||||
descriptor->GetLocationPath(&path);
|
||||
GeneratedCodeInfo::Annotation annotation;
|
||||
for (int i = 0; i < path.size(); ++i) {
|
||||
annotation.add_path(path[i]);
|
||||
}
|
||||
annotation.set_source_file(descriptor->file()->name());
|
||||
return annotation.SerializeAsString();
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
void PrintFieldComment(const Formatter& format, const T* field) {
|
||||
// Print the field's (or oneof's) proto-syntax definition as a comment.
|
||||
// We don't want to print group bodies so we cut off after the first
|
||||
// line.
|
||||
DebugStringOptions options;
|
||||
options.elide_group_body = true;
|
||||
options.elide_oneof_body = true;
|
||||
std::string def = field->DebugStringWithOptions(options);
|
||||
format("// $1$\n", def.substr(0, def.find_first_of('\n')));
|
||||
}
|
||||
|
||||
class PROTOC_EXPORT NamespaceOpener {
|
||||
public:
|
||||
explicit NamespaceOpener(const Formatter& format)
|
||||
: printer_(format.printer()) {}
|
||||
NamespaceOpener(const std::string& name, const Formatter& format)
|
||||
: NamespaceOpener(format) {
|
||||
ChangeTo(name);
|
||||
}
|
||||
~NamespaceOpener() { ChangeTo(""); }
|
||||
|
||||
void ChangeTo(const std::string& name) {
|
||||
std::vector<std::string> new_stack_ =
|
||||
Split(name, "::", true);
|
||||
int len = std::min(name_stack_.size(), new_stack_.size());
|
||||
int common_idx = 0;
|
||||
while (common_idx < len) {
|
||||
if (name_stack_[common_idx] != new_stack_[common_idx]) break;
|
||||
common_idx++;
|
||||
}
|
||||
for (int i = name_stack_.size() - 1; i >= common_idx; i--) {
|
||||
if (name_stack_[i] == "PROTOBUF_NAMESPACE_ID") {
|
||||
printer_->Print("PROTOBUF_NAMESPACE_CLOSE\n");
|
||||
} else {
|
||||
printer_->Print("} // namespace $ns$\n", "ns", name_stack_[i]);
|
||||
}
|
||||
}
|
||||
name_stack_.swap(new_stack_);
|
||||
for (int i = common_idx; i < name_stack_.size(); i++) {
|
||||
if (name_stack_[i] == "PROTOBUF_NAMESPACE_ID") {
|
||||
printer_->Print("PROTOBUF_NAMESPACE_OPEN\n");
|
||||
} else {
|
||||
printer_->Print("namespace $ns$ {\n", "ns", name_stack_[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
io::Printer* printer_;
|
||||
std::vector<std::string> name_stack_;
|
||||
};
|
||||
|
||||
enum Utf8CheckMode {
|
||||
STRICT = 0, // Parsing will fail if non UTF-8 data is in string fields.
|
||||
VERIFY = 1, // Only log an error but parsing will succeed.
|
||||
NONE = 2, // No UTF-8 check.
|
||||
};
|
||||
|
||||
Utf8CheckMode GetUtf8CheckMode(const FieldDescriptor* field,
|
||||
const Options& options);
|
||||
|
||||
void GenerateUtf8CheckCodeForString(const FieldDescriptor* field,
|
||||
const Options& options, bool for_parse,
|
||||
const char* parameters,
|
||||
const Formatter& format);
|
||||
|
||||
void GenerateUtf8CheckCodeForCord(const FieldDescriptor* field,
|
||||
const Options& options, bool for_parse,
|
||||
const char* parameters,
|
||||
const Formatter& format);
|
||||
|
||||
template <typename T>
|
||||
struct FieldRangeImpl {
|
||||
struct Iterator {
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
using value_type = const FieldDescriptor*;
|
||||
using difference_type = int;
|
||||
|
||||
value_type operator*() { return descriptor->field(idx); }
|
||||
|
||||
friend bool operator==(const Iterator& a, const Iterator& b) {
|
||||
GOOGLE_DCHECK(a.descriptor == b.descriptor);
|
||||
return a.idx == b.idx;
|
||||
}
|
||||
friend bool operator!=(const Iterator& a, const Iterator& b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
Iterator& operator++() {
|
||||
idx++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
int idx;
|
||||
const T* descriptor;
|
||||
};
|
||||
|
||||
Iterator begin() const { return {0, descriptor}; }
|
||||
Iterator end() const { return {descriptor->field_count(), descriptor}; }
|
||||
|
||||
const T* descriptor;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
FieldRangeImpl<T> FieldRange(const T* desc) {
|
||||
return {desc};
|
||||
}
|
||||
|
||||
struct OneOfRangeImpl {
|
||||
struct Iterator {
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
using value_type = const OneofDescriptor*;
|
||||
using difference_type = int;
|
||||
|
||||
value_type operator*() { return descriptor->oneof_decl(idx); }
|
||||
|
||||
friend bool operator==(const Iterator& a, const Iterator& b) {
|
||||
GOOGLE_DCHECK(a.descriptor == b.descriptor);
|
||||
return a.idx == b.idx;
|
||||
}
|
||||
friend bool operator!=(const Iterator& a, const Iterator& b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
Iterator& operator++() {
|
||||
idx++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
int idx;
|
||||
const Descriptor* descriptor;
|
||||
};
|
||||
|
||||
Iterator begin() const { return {0, descriptor}; }
|
||||
Iterator end() const {
|
||||
return {descriptor->real_oneof_decl_count(), descriptor};
|
||||
}
|
||||
|
||||
const Descriptor* descriptor;
|
||||
};
|
||||
|
||||
inline OneOfRangeImpl OneOfRange(const Descriptor* desc) { return {desc}; }
|
||||
|
||||
void GenerateParserLoop(const Descriptor* descriptor, int num_hasbits,
|
||||
const Options& options,
|
||||
MessageSCCAnalyzer* scc_analyzer, io::Printer* printer);
|
||||
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#include <google/protobuf/port_undef.inc>
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_CPP_HELPERS_H__
|
||||
296
ubuntu/google/protobuf/compiler/cpp/cpp_map_field.cc
Normal file
296
ubuntu/google/protobuf/compiler/cpp/cpp_map_field.cc
Normal file
@@ -0,0 +1,296 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <google/protobuf/compiler/cpp/cpp_map_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 {
|
||||
|
||||
bool IsProto3Field(const FieldDescriptor* field_descriptor) {
|
||||
const FileDescriptor* file_descriptor = field_descriptor->file();
|
||||
return file_descriptor->syntax() == FileDescriptor::SYNTAX_PROTO3;
|
||||
}
|
||||
|
||||
void SetMessageVariables(const FieldDescriptor* descriptor,
|
||||
std::map<std::string, std::string>* variables,
|
||||
const Options& options) {
|
||||
SetCommonFieldVariables(descriptor, variables, options);
|
||||
(*variables)["type"] = ClassName(descriptor->message_type(), false);
|
||||
(*variables)["full_name"] = descriptor->full_name();
|
||||
|
||||
const FieldDescriptor* key =
|
||||
descriptor->message_type()->FindFieldByName("key");
|
||||
const FieldDescriptor* val =
|
||||
descriptor->message_type()->FindFieldByName("value");
|
||||
(*variables)["key_cpp"] = PrimitiveTypeName(options, key->cpp_type());
|
||||
switch (val->cpp_type()) {
|
||||
case FieldDescriptor::CPPTYPE_MESSAGE:
|
||||
(*variables)["val_cpp"] = FieldMessageTypeName(val, options);
|
||||
break;
|
||||
case FieldDescriptor::CPPTYPE_ENUM:
|
||||
(*variables)["val_cpp"] = ClassName(val->enum_type(), true);
|
||||
break;
|
||||
default:
|
||||
(*variables)["val_cpp"] = PrimitiveTypeName(options, val->cpp_type());
|
||||
}
|
||||
(*variables)["key_wire_type"] =
|
||||
"TYPE_" + ToUpper(DeclaredTypeMethodName(key->type()));
|
||||
(*variables)["val_wire_type"] =
|
||||
"TYPE_" + ToUpper(DeclaredTypeMethodName(val->type()));
|
||||
(*variables)["map_classname"] = ClassName(descriptor->message_type(), false);
|
||||
(*variables)["number"] = StrCat(descriptor->number());
|
||||
(*variables)["tag"] = StrCat(internal::WireFormat::MakeTag(descriptor));
|
||||
|
||||
if (HasDescriptorMethods(descriptor->file(), options)) {
|
||||
(*variables)["lite"] = "";
|
||||
} else {
|
||||
(*variables)["lite"] = "Lite";
|
||||
}
|
||||
}
|
||||
|
||||
MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor,
|
||||
const Options& options)
|
||||
: FieldGenerator(descriptor, options) {
|
||||
SetMessageVariables(descriptor, &variables_, options);
|
||||
}
|
||||
|
||||
MapFieldGenerator::~MapFieldGenerator() {}
|
||||
|
||||
void MapFieldGenerator::GeneratePrivateMembers(io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format(
|
||||
"::$proto_ns$::internal::MapField$lite$<\n"
|
||||
" $map_classname$,\n"
|
||||
" $key_cpp$, $val_cpp$,\n"
|
||||
" ::$proto_ns$::internal::WireFormatLite::$key_wire_type$,\n"
|
||||
" ::$proto_ns$::internal::WireFormatLite::$val_wire_type$> "
|
||||
"$name$_;\n");
|
||||
}
|
||||
|
||||
void MapFieldGenerator::GenerateAccessorDeclarations(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format(
|
||||
"private:\n"
|
||||
"const ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >&\n"
|
||||
" ${1$_internal_$name$$}$() const;\n"
|
||||
"::$proto_ns$::Map< $key_cpp$, $val_cpp$ >*\n"
|
||||
" ${1$_internal_mutable_$name$$}$();\n"
|
||||
"public:\n"
|
||||
"$deprecated_attr$const ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >&\n"
|
||||
" ${1$$name$$}$() const;\n"
|
||||
"$deprecated_attr$::$proto_ns$::Map< $key_cpp$, $val_cpp$ >*\n"
|
||||
" ${1$mutable_$name$$}$();\n",
|
||||
descriptor_);
|
||||
}
|
||||
|
||||
void MapFieldGenerator::GenerateInlineAccessorDefinitions(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format(
|
||||
"inline const ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >&\n"
|
||||
"$classname$::_internal_$name$() const {\n"
|
||||
" return $name$_.GetMap();\n"
|
||||
"}\n"
|
||||
"inline const ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >&\n"
|
||||
"$classname$::$name$() const {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_map:$full_name$)\n"
|
||||
" return _internal_$name$();\n"
|
||||
"}\n"
|
||||
"inline ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >*\n"
|
||||
"$classname$::_internal_mutable_$name$() {\n"
|
||||
" return $name$_.MutableMap();\n"
|
||||
"}\n"
|
||||
"inline ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >*\n"
|
||||
"$classname$::mutable_$name$() {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_mutable_map:$full_name$)\n"
|
||||
" return _internal_mutable_$name$();\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
void MapFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("$name$_.Clear();\n");
|
||||
}
|
||||
|
||||
void MapFieldGenerator::GenerateMergingCode(io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("$name$_.MergeFrom(from.$name$_);\n");
|
||||
}
|
||||
|
||||
void MapFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("$name$_.Swap(&other->$name$_);\n");
|
||||
}
|
||||
|
||||
void MapFieldGenerator::GenerateCopyConstructorCode(
|
||||
io::Printer* printer) const {
|
||||
GenerateConstructorCode(printer);
|
||||
GenerateMergingCode(printer);
|
||||
}
|
||||
|
||||
static void GenerateSerializationLoop(const Formatter& format, bool string_key,
|
||||
bool string_value,
|
||||
bool is_deterministic) {
|
||||
std::string ptr;
|
||||
if (is_deterministic) {
|
||||
format("for (size_type i = 0; i < n; i++) {\n");
|
||||
ptr = string_key ? "items[static_cast<ptrdiff_t>(i)]"
|
||||
: "items[static_cast<ptrdiff_t>(i)].second";
|
||||
} else {
|
||||
format(
|
||||
"for (::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
|
||||
" it = this->_internal_$name$().begin();\n"
|
||||
" it != this->_internal_$name$().end(); ++it) {\n");
|
||||
ptr = "it";
|
||||
}
|
||||
format.Indent();
|
||||
|
||||
format(
|
||||
"target = $map_classname$::Funcs::InternalSerialize($number$, "
|
||||
"$1$->first, $1$->second, target, stream);\n",
|
||||
ptr);
|
||||
|
||||
if (string_key || string_value) {
|
||||
// ptr is either an actual pointer or an iterator, either way we can
|
||||
// create a pointer by taking the address after de-referencing it.
|
||||
format("Utf8Check::Check(&(*$1$));\n", ptr);
|
||||
}
|
||||
|
||||
format.Outdent();
|
||||
format("}\n");
|
||||
}
|
||||
|
||||
void MapFieldGenerator::GenerateSerializeWithCachedSizesToArray(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("if (!this->_internal_$name$().empty()) {\n");
|
||||
format.Indent();
|
||||
const FieldDescriptor* key_field =
|
||||
descriptor_->message_type()->FindFieldByName("key");
|
||||
const FieldDescriptor* value_field =
|
||||
descriptor_->message_type()->FindFieldByName("value");
|
||||
const bool string_key = key_field->type() == FieldDescriptor::TYPE_STRING;
|
||||
const bool string_value = value_field->type() == FieldDescriptor::TYPE_STRING;
|
||||
|
||||
format(
|
||||
"typedef ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_pointer\n"
|
||||
" ConstPtr;\n");
|
||||
if (string_key) {
|
||||
format(
|
||||
"typedef ConstPtr SortItem;\n"
|
||||
"typedef ::$proto_ns$::internal::"
|
||||
"CompareByDerefFirst<SortItem> Less;\n");
|
||||
} else {
|
||||
format(
|
||||
"typedef ::$proto_ns$::internal::SortItem< $key_cpp$, ConstPtr > "
|
||||
"SortItem;\n"
|
||||
"typedef ::$proto_ns$::internal::CompareByFirstField<SortItem> "
|
||||
"Less;\n");
|
||||
}
|
||||
bool utf8_check = string_key || string_value;
|
||||
if (utf8_check) {
|
||||
format(
|
||||
"struct Utf8Check {\n"
|
||||
" static void Check(ConstPtr p) {\n");
|
||||
format.Indent();
|
||||
format.Indent();
|
||||
if (string_key) {
|
||||
GenerateUtf8CheckCodeForString(
|
||||
key_field, options_, false,
|
||||
"p->first.data(), static_cast<int>(p->first.length()),\n", format);
|
||||
}
|
||||
if (string_value) {
|
||||
GenerateUtf8CheckCodeForString(
|
||||
value_field, options_, false,
|
||||
"p->second.data(), static_cast<int>(p->second.length()),\n", format);
|
||||
}
|
||||
format.Outdent();
|
||||
format.Outdent();
|
||||
format(
|
||||
" }\n"
|
||||
"};\n");
|
||||
}
|
||||
|
||||
format(
|
||||
"\n"
|
||||
"if (stream->IsSerializationDeterministic() &&\n"
|
||||
" this->_internal_$name$().size() > 1) {\n"
|
||||
" ::std::unique_ptr<SortItem[]> items(\n"
|
||||
" new SortItem[this->_internal_$name$().size()]);\n"
|
||||
" typedef ::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::size_type "
|
||||
"size_type;\n"
|
||||
" size_type n = 0;\n"
|
||||
" for (::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
|
||||
" it = this->_internal_$name$().begin();\n"
|
||||
" it != this->_internal_$name$().end(); ++it, ++n) {\n"
|
||||
" items[static_cast<ptrdiff_t>(n)] = SortItem(&*it);\n"
|
||||
" }\n"
|
||||
" ::std::sort(&items[0], &items[static_cast<ptrdiff_t>(n)], Less());\n");
|
||||
format.Indent();
|
||||
GenerateSerializationLoop(format, string_key, string_value, true);
|
||||
format.Outdent();
|
||||
format("} else {\n");
|
||||
format.Indent();
|
||||
GenerateSerializationLoop(format, string_key, string_value, false);
|
||||
format.Outdent();
|
||||
format("}\n");
|
||||
format.Outdent();
|
||||
format("}\n");
|
||||
}
|
||||
|
||||
void MapFieldGenerator::GenerateByteSize(io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format(
|
||||
"total_size += $tag_size$ *\n"
|
||||
" "
|
||||
"::$proto_ns$::internal::FromIntSize(this->_internal_$name$_size());\n"
|
||||
"for (::$proto_ns$::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
|
||||
" it = this->_internal_$name$().begin();\n"
|
||||
" it != this->_internal_$name$().end(); ++it) {\n"
|
||||
" total_size += $map_classname$::Funcs::ByteSizeLong(it->first, "
|
||||
"it->second);\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
70
ubuntu/google/protobuf/compiler/cpp/cpp_map_field.h
Normal file
70
ubuntu/google/protobuf/compiler/cpp/cpp_map_field.h
Normal file
@@ -0,0 +1,70 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_MAP_FIELD_H__
|
||||
#define GOOGLE_PROTOBUF_COMPILER_CPP_MAP_FIELD_H__
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include <google/protobuf/compiler/cpp/cpp_message_field.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace cpp {
|
||||
|
||||
class MapFieldGenerator : public FieldGenerator {
|
||||
public:
|
||||
MapFieldGenerator(const FieldDescriptor* descriptor, const Options& options);
|
||||
~MapFieldGenerator();
|
||||
|
||||
// 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 GenerateCopyConstructorCode(io::Printer* printer) const;
|
||||
void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
|
||||
void GenerateByteSize(io::Printer* printer) const;
|
||||
|
||||
private:
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapFieldGenerator);
|
||||
};
|
||||
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_CPP_MAP_FIELD_H__
|
||||
4069
ubuntu/google/protobuf/compiler/cpp/cpp_message.cc
Normal file
4069
ubuntu/google/protobuf/compiler/cpp/cpp_message.cc
Normal file
File diff suppressed because it is too large
Load Diff
215
ubuntu/google/protobuf/compiler/cpp/cpp_message.h
Normal file
215
ubuntu/google/protobuf/compiler/cpp/cpp_message.h
Normal file
@@ -0,0 +1,215 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Author: kenton@google.com (Kenton Varda)
|
||||
// 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 <set>
|
||||
#include <string>
|
||||
#include <google/protobuf/compiler/cpp/cpp_field.h>
|
||||
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
|
||||
#include <google/protobuf/compiler/cpp/cpp_message_layout_helper.h>
|
||||
#include <google/protobuf/compiler/cpp/cpp_options.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace io {
|
||||
class Printer; // printer.h
|
||||
}
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace cpp {
|
||||
|
||||
class EnumGenerator; // enum.h
|
||||
class ExtensionGenerator; // extension.h
|
||||
|
||||
class MessageGenerator {
|
||||
public:
|
||||
// See generator.cc for the meaning of dllexport_decl.
|
||||
MessageGenerator(const Descriptor* descriptor,
|
||||
const std::map<std::string, std::string>& vars,
|
||||
int index_in_file_messages, const Options& options,
|
||||
MessageSCCAnalyzer* scc_analyzer);
|
||||
~MessageGenerator();
|
||||
|
||||
// Append the two types of nested generators to the corresponding vector.
|
||||
void AddGenerators(
|
||||
std::vector<std::unique_ptr<EnumGenerator>>* enum_generators,
|
||||
std::vector<std::unique_ptr<ExtensionGenerator>>* extension_generators);
|
||||
|
||||
// Generate definitions for this class and all its nested types.
|
||||
void GenerateClassDefinition(io::Printer* printer);
|
||||
|
||||
// Generate definitions of inline methods (placed at the end of the header
|
||||
// file).
|
||||
void GenerateInlineMethods(io::Printer* printer);
|
||||
|
||||
// Source file stuff.
|
||||
|
||||
// Generate all non-inline methods for this class.
|
||||
void GenerateClassMethods(io::Printer* printer);
|
||||
|
||||
// Generate source file code that should go outside any namespace.
|
||||
void GenerateSourceInProto2Namespace(io::Printer* printer);
|
||||
|
||||
private:
|
||||
// Generate declarations and definitions of accessors for fields.
|
||||
void GenerateFieldAccessorDeclarations(io::Printer* printer);
|
||||
void GenerateFieldAccessorDefinitions(io::Printer* printer);
|
||||
|
||||
// Generate the table-driven parsing array. Returns the number of entries
|
||||
// generated.
|
||||
size_t GenerateParseOffsets(io::Printer* printer);
|
||||
size_t GenerateParseAuxTable(io::Printer* printer);
|
||||
// Generates a ParseTable entry. Returns whether the proto uses
|
||||
// table-driven parsing.
|
||||
bool GenerateParseTable(io::Printer* printer, size_t offset,
|
||||
size_t aux_offset);
|
||||
|
||||
// Generate the field offsets array. Returns the a pair of the total number
|
||||
// of entries generated and the index of the first has_bit entry.
|
||||
std::pair<size_t, size_t> GenerateOffsets(io::Printer* printer);
|
||||
void GenerateSchema(io::Printer* printer, int offset, int has_offset);
|
||||
// For each field generates a table entry describing the field for the
|
||||
// table driven serializer.
|
||||
int GenerateFieldMetadata(io::Printer* printer);
|
||||
|
||||
// Generate constructors and destructor.
|
||||
void GenerateStructors(io::Printer* printer);
|
||||
|
||||
// The compiler typically generates multiple copies of each constructor and
|
||||
// destructor: http://gcc.gnu.org/bugs.html#nonbugs_cxx
|
||||
// Placing common code in a separate method reduces the generated code size.
|
||||
//
|
||||
// Generate the shared constructor code.
|
||||
void GenerateSharedConstructorCode(io::Printer* printer);
|
||||
// Generate the shared destructor code.
|
||||
void GenerateSharedDestructorCode(io::Printer* printer);
|
||||
// Generate the arena-specific destructor code.
|
||||
void GenerateArenaDestructorCode(io::Printer* printer);
|
||||
|
||||
// Generate 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);
|
||||
void GenerateSerializeWithCachedSizesBodyShuffled(io::Printer* printer);
|
||||
void GenerateByteSize(io::Printer* printer);
|
||||
void GenerateMergeFrom(io::Printer* printer);
|
||||
void GenerateClassSpecificMergeFrom(io::Printer* printer);
|
||||
void GenerateCopyFrom(io::Printer* printer);
|
||||
void GenerateSwap(io::Printer* printer);
|
||||
void GenerateIsInitialized(io::Printer* printer);
|
||||
|
||||
// Helpers for GenerateSerializeWithCachedSizes().
|
||||
//
|
||||
// cached_has_bit_index maintains that:
|
||||
// cached_has_bits = _has_bits_[cached_has_bit_index]
|
||||
// for cached_has_bit_index >= 0
|
||||
void GenerateSerializeOneField(io::Printer* printer,
|
||||
const FieldDescriptor* field,
|
||||
int cached_has_bits_index);
|
||||
// Generate a switch statement to serialize 2+ fields from the same oneof.
|
||||
// Or, if fields.size() == 1, just call GenerateSerializeOneField().
|
||||
void GenerateSerializeOneofFields(
|
||||
io::Printer* printer, const std::vector<const FieldDescriptor*>& fields);
|
||||
void GenerateSerializeOneExtensionRange(
|
||||
io::Printer* printer, const Descriptor::ExtensionRange* range);
|
||||
|
||||
// Generates has_foo() functions and variables for singular field has-bits.
|
||||
void GenerateSingularFieldHasBits(const FieldDescriptor* field,
|
||||
Formatter format);
|
||||
// Generates has_foo() functions and variables for oneof field has-bits.
|
||||
void GenerateOneofHasBits(io::Printer* printer);
|
||||
// Generates has_foo_bar() functions for oneof members.
|
||||
void GenerateOneofMemberHasBits(const FieldDescriptor* field,
|
||||
const Formatter& format);
|
||||
// Generates the clear_foo() method for a field.
|
||||
void GenerateFieldClear(const FieldDescriptor* field, bool is_inline,
|
||||
Formatter format);
|
||||
|
||||
void GenerateConstructorBody(io::Printer* printer,
|
||||
std::vector<bool> already_processed,
|
||||
bool copy_constructor) const;
|
||||
|
||||
size_t HasBitsSize() const;
|
||||
int HasBitIndex(const FieldDescriptor* a) const;
|
||||
int HasByteIndex(const FieldDescriptor* a) const;
|
||||
int HasWordIndex(const FieldDescriptor* a) const;
|
||||
bool SameHasByte(const FieldDescriptor* a, const FieldDescriptor* b) const;
|
||||
std::vector<uint32> RequiredFieldsBitMask() const;
|
||||
|
||||
const Descriptor* descriptor_;
|
||||
int index_in_file_messages_;
|
||||
std::string classname_;
|
||||
Options options_;
|
||||
FieldGeneratorMap field_generators_;
|
||||
// optimized_order_ is the order we layout the message's fields in the
|
||||
// class. This is reused to initialize the fields in-order for cache
|
||||
// efficiency.
|
||||
//
|
||||
// optimized_order_ excludes oneof fields and weak fields.
|
||||
std::vector<const FieldDescriptor*> optimized_order_;
|
||||
std::vector<int> has_bit_indices_;
|
||||
int max_has_bit_index_;
|
||||
std::vector<const EnumGenerator*> enum_generators_;
|
||||
std::vector<const ExtensionGenerator*> extension_generators_;
|
||||
int num_required_fields_;
|
||||
int num_weak_fields_;
|
||||
// table_driven_ indicates the generated message uses table-driven parsing.
|
||||
bool table_driven_;
|
||||
|
||||
std::unique_ptr<MessageLayoutHelper> message_layout_helper_;
|
||||
|
||||
MessageSCCAnalyzer* scc_analyzer_;
|
||||
|
||||
std::map<std::string, std::string> variables_;
|
||||
|
||||
friend class FileGenerator;
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator);
|
||||
};
|
||||
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_H__
|
||||
815
ubuntu/google/protobuf/compiler/cpp/cpp_message_field.cc
Normal file
815
ubuntu/google/protobuf/compiler/cpp/cpp_message_field.cc
Normal file
@@ -0,0 +1,815 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 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 {
|
||||
std::string ReinterpretCast(const std::string& type,
|
||||
const std::string& expression,
|
||||
bool implicit_weak_field) {
|
||||
if (implicit_weak_field) {
|
||||
return "reinterpret_cast< " + type + " >(" + expression + ")";
|
||||
} else {
|
||||
return expression;
|
||||
}
|
||||
}
|
||||
|
||||
void SetMessageVariables(const FieldDescriptor* descriptor,
|
||||
const Options& options, bool implicit_weak,
|
||||
std::map<std::string, std::string>* variables) {
|
||||
SetCommonFieldVariables(descriptor, variables, options);
|
||||
(*variables)["type"] = FieldMessageTypeName(descriptor, options);
|
||||
(*variables)["casted_member"] = ReinterpretCast(
|
||||
(*variables)["type"] + "*", (*variables)["name"] + "_", implicit_weak);
|
||||
(*variables)["type_default_instance"] =
|
||||
QualifiedDefaultInstanceName(descriptor->message_type(), options);
|
||||
(*variables)["type_default_instance_ptr"] =
|
||||
QualifiedDefaultInstancePtr(descriptor->message_type(), options);
|
||||
(*variables)["type_reference_function"] =
|
||||
implicit_weak ? (" ::" + (*variables)["proto_ns"] +
|
||||
"::internal::StrongReference(reinterpret_cast<const " +
|
||||
(*variables)["type"] + "&>(\n" +
|
||||
(*variables)["type_default_instance"] + "));\n")
|
||||
: "";
|
||||
// NOTE: Escaped here to unblock proto1->proto2 migration.
|
||||
// TODO(liujisi): Extend this to apply for other conflicting methods.
|
||||
(*variables)["release_name"] =
|
||||
SafeFunctionName(descriptor->containing_type(), descriptor, "release_");
|
||||
(*variables)["full_name"] = descriptor->full_name();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// ===================================================================
|
||||
|
||||
MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor,
|
||||
const Options& options,
|
||||
MessageSCCAnalyzer* scc_analyzer)
|
||||
: FieldGenerator(descriptor, options),
|
||||
implicit_weak_field_(
|
||||
IsImplicitWeakField(descriptor, options, scc_analyzer)) {
|
||||
SetMessageVariables(descriptor, options, implicit_weak_field_, &variables_);
|
||||
}
|
||||
|
||||
MessageFieldGenerator::~MessageFieldGenerator() {}
|
||||
|
||||
void MessageFieldGenerator::GeneratePrivateMembers(io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
if (implicit_weak_field_) {
|
||||
format("::$proto_ns$::MessageLite* $name$_;\n");
|
||||
} else {
|
||||
format("$type$* $name$_;\n");
|
||||
}
|
||||
}
|
||||
|
||||
void MessageFieldGenerator::GenerateAccessorDeclarations(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
if (IsFieldStripped(descriptor_, options_)) {
|
||||
format(
|
||||
"$deprecated_attr$const $type$& ${1$$name$$}$() const { "
|
||||
"__builtin_trap(); }\n"
|
||||
"$deprecated_attr$$type$* ${1$$release_name$$}$() { "
|
||||
"__builtin_trap(); }\n"
|
||||
"$deprecated_attr$$type$* ${1$mutable_$name$$}$() { "
|
||||
"__builtin_trap(); }\n"
|
||||
"$deprecated_attr$void ${1$set_allocated_$name$$}$"
|
||||
"($type$* $name$) { __builtin_trap(); }\n"
|
||||
"$deprecated_attr$void "
|
||||
"${1$unsafe_arena_set_allocated_$name$$}$(\n"
|
||||
" $type$* $name$) { __builtin_trap(); }\n"
|
||||
"$deprecated_attr$$type$* ${1$unsafe_arena_release_$name$$}$() { "
|
||||
"__builtin_trap(); }\n",
|
||||
descriptor_);
|
||||
return;
|
||||
}
|
||||
format(
|
||||
"$deprecated_attr$const $type$& ${1$$name$$}$() const;\n"
|
||||
"$deprecated_attr$$type$* ${1$$release_name$$}$();\n"
|
||||
"$deprecated_attr$$type$* ${1$mutable_$name$$}$();\n"
|
||||
"$deprecated_attr$void ${1$set_allocated_$name$$}$"
|
||||
"($type$* $name$);\n",
|
||||
descriptor_);
|
||||
if (!IsFieldStripped(descriptor_, options_)) {
|
||||
format(
|
||||
"private:\n"
|
||||
"const $type$& ${1$_internal_$name$$}$() const;\n"
|
||||
"$type$* ${1$_internal_mutable_$name$$}$();\n"
|
||||
"public:\n",
|
||||
descriptor_);
|
||||
}
|
||||
format(
|
||||
"$deprecated_attr$void "
|
||||
"${1$unsafe_arena_set_allocated_$name$$}$(\n"
|
||||
" $type$* $name$);\n"
|
||||
"$deprecated_attr$$type$* ${1$unsafe_arena_release_$name$$}$();\n",
|
||||
descriptor_);
|
||||
}
|
||||
|
||||
void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions(
|
||||
io::Printer* printer) const {
|
||||
}
|
||||
|
||||
void MessageFieldGenerator::GenerateInlineAccessorDefinitions(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format(
|
||||
"inline const $type$& $classname$::_internal_$name$() const {\n"
|
||||
"$type_reference_function$"
|
||||
" const $type$* p = $casted_member$;\n"
|
||||
" return p != nullptr ? *p : reinterpret_cast<const $type$&>(\n"
|
||||
" $type_default_instance$);\n"
|
||||
"}\n"
|
||||
"inline const $type$& $classname$::$name$() const {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_get:$full_name$)\n"
|
||||
" return _internal_$name$();\n"
|
||||
"}\n");
|
||||
|
||||
format(
|
||||
"inline void $classname$::unsafe_arena_set_allocated_$name$(\n"
|
||||
" $type$* $name$) {\n"
|
||||
"$annotate_accessor$"
|
||||
// If we're not on an arena, free whatever we were holding before.
|
||||
// (If we are on arena, we can just forget the earlier pointer.)
|
||||
" if (GetArena() == nullptr) {\n"
|
||||
" delete reinterpret_cast<::$proto_ns$::MessageLite*>($name$_);\n"
|
||||
" }\n");
|
||||
if (implicit_weak_field_) {
|
||||
format(
|
||||
" $name$_ = "
|
||||
"reinterpret_cast<::$proto_ns$::MessageLite*>($name$);\n");
|
||||
} else {
|
||||
format(" $name$_ = $name$;\n");
|
||||
}
|
||||
format(
|
||||
" if ($name$) {\n"
|
||||
" $set_hasbit$\n"
|
||||
" } else {\n"
|
||||
" $clear_hasbit$\n"
|
||||
" }\n"
|
||||
" // @@protoc_insertion_point(field_unsafe_arena_set_allocated"
|
||||
":$full_name$)\n"
|
||||
"}\n");
|
||||
format(
|
||||
"inline $type$* $classname$::$release_name$() {\n"
|
||||
"$type_reference_function$"
|
||||
" $clear_hasbit$\n"
|
||||
" $type$* temp = $casted_member$;\n"
|
||||
" $name$_ = nullptr;\n"
|
||||
" if (GetArena() != nullptr) {\n"
|
||||
" temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n"
|
||||
" }\n"
|
||||
" return temp;\n"
|
||||
"}\n"
|
||||
"inline $type$* $classname$::unsafe_arena_release_$name$() {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_release:$full_name$)\n"
|
||||
"$type_reference_function$"
|
||||
" $clear_hasbit$\n"
|
||||
" $type$* temp = $casted_member$;\n"
|
||||
" $name$_ = nullptr;\n"
|
||||
" return temp;\n"
|
||||
"}\n");
|
||||
|
||||
format(
|
||||
"inline $type$* $classname$::_internal_mutable_$name$() {\n"
|
||||
"$type_reference_function$"
|
||||
" $set_hasbit$\n"
|
||||
" if ($name$_ == nullptr) {\n"
|
||||
" auto* p = CreateMaybeMessage<$type$>(GetArena());\n");
|
||||
if (implicit_weak_field_) {
|
||||
format(" $name$_ = reinterpret_cast<::$proto_ns$::MessageLite*>(p);\n");
|
||||
} else {
|
||||
format(" $name$_ = p;\n");
|
||||
}
|
||||
format(
|
||||
" }\n"
|
||||
" return $casted_member$;\n"
|
||||
"}\n"
|
||||
"inline $type$* $classname$::mutable_$name$() {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_mutable:$full_name$)\n"
|
||||
" return _internal_mutable_$name$();\n"
|
||||
"}\n");
|
||||
|
||||
// We handle the most common case inline, and delegate less common cases to
|
||||
// the slow fallback function.
|
||||
format(
|
||||
"inline void $classname$::set_allocated_$name$($type$* $name$) {\n"
|
||||
"$annotate_accessor$"
|
||||
" ::$proto_ns$::Arena* message_arena = GetArena();\n");
|
||||
format(" if (message_arena == nullptr) {\n");
|
||||
if (IsCrossFileMessage(descriptor_)) {
|
||||
format(
|
||||
" delete reinterpret_cast< ::$proto_ns$::MessageLite*>($name$_);\n");
|
||||
} else {
|
||||
format(" delete $name$_;\n");
|
||||
}
|
||||
format(
|
||||
" }\n"
|
||||
" if ($name$) {\n");
|
||||
if (IsCrossFileMessage(descriptor_)) {
|
||||
// We have to read the arena through the virtual method, because the type
|
||||
// isn't defined in this file.
|
||||
format(
|
||||
" ::$proto_ns$::Arena* submessage_arena =\n"
|
||||
" "
|
||||
"reinterpret_cast<::$proto_ns$::MessageLite*>($name$)->GetArena();\n");
|
||||
} else {
|
||||
format(
|
||||
" ::$proto_ns$::Arena* submessage_arena =\n"
|
||||
" ::$proto_ns$::Arena::GetArena($name$);\n");
|
||||
}
|
||||
format(
|
||||
" if (message_arena != submessage_arena) {\n"
|
||||
" $name$ = ::$proto_ns$::internal::GetOwnedMessage(\n"
|
||||
" message_arena, $name$, submessage_arena);\n"
|
||||
" }\n"
|
||||
" $set_hasbit$\n"
|
||||
" } else {\n"
|
||||
" $clear_hasbit$\n"
|
||||
" }\n");
|
||||
if (implicit_weak_field_) {
|
||||
format(" $name$_ = reinterpret_cast<MessageLite*>($name$);\n");
|
||||
} else {
|
||||
format(" $name$_ = $name$;\n");
|
||||
}
|
||||
format(
|
||||
" // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
void MessageFieldGenerator::GenerateInternalAccessorDeclarations(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
if (implicit_weak_field_) {
|
||||
format(
|
||||
"static const ::$proto_ns$::MessageLite& $name$("
|
||||
"const $classname$* msg);\n"
|
||||
"static ::$proto_ns$::MessageLite* mutable_$name$("
|
||||
"$classname$* msg);\n");
|
||||
} else {
|
||||
format("static const $type$& $name$(const $classname$* msg);\n");
|
||||
}
|
||||
}
|
||||
|
||||
void MessageFieldGenerator::GenerateInternalAccessorDefinitions(
|
||||
io::Printer* printer) const {
|
||||
// In theory, these accessors could be inline in _Internal. However, in
|
||||
// practice, the linker is then not able to throw them out making implicit
|
||||
// weak dependencies not work at all.
|
||||
Formatter format(printer, variables_);
|
||||
if (implicit_weak_field_) {
|
||||
// These private accessors are used by MergeFrom and
|
||||
// MergePartialFromCodedStream, and their purpose is to provide access to
|
||||
// the field without creating a strong dependency on the message type.
|
||||
format(
|
||||
"const ::$proto_ns$::MessageLite& $classname$::_Internal::$name$(\n"
|
||||
" const $classname$* msg) {\n"
|
||||
" if (msg->$name$_ != nullptr) {\n"
|
||||
" return *msg->$name$_;\n"
|
||||
" } else if ($type_default_instance_ptr$ != nullptr) {\n"
|
||||
" return *reinterpret_cast<const ::$proto_ns$::MessageLite*>(\n"
|
||||
" $type_default_instance_ptr$);\n"
|
||||
" } else {\n"
|
||||
" return "
|
||||
"*::$proto_ns$::internal::ImplicitWeakMessage::default_instance();\n"
|
||||
" }\n"
|
||||
"}\n");
|
||||
format(
|
||||
"::$proto_ns$::MessageLite*\n"
|
||||
"$classname$::_Internal::mutable_$name$($classname$* msg) {\n");
|
||||
if (HasFieldPresence(descriptor_->file())) {
|
||||
format(" msg->$set_hasbit$\n");
|
||||
}
|
||||
format(
|
||||
" if (msg->$name$_ == nullptr) {\n"
|
||||
" if ($type_default_instance_ptr$ == nullptr) {\n"
|
||||
" msg->$name$_ = ::$proto_ns$::Arena::CreateMessage<\n"
|
||||
" ::$proto_ns$::internal::ImplicitWeakMessage>(\n"
|
||||
" msg->GetArena());\n"
|
||||
" } else {\n"
|
||||
" msg->$name$_ = reinterpret_cast<const "
|
||||
"::$proto_ns$::MessageLite*>(\n"
|
||||
" $type_default_instance_ptr$)->New(msg->GetArena());\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" return msg->$name$_;\n"
|
||||
"}\n");
|
||||
} else {
|
||||
// This inline accessor directly returns member field and is used in
|
||||
// Serialize such that AFDO profile correctly captures access information to
|
||||
// message fields under serialize.
|
||||
format(
|
||||
"const $type$&\n"
|
||||
"$classname$::_Internal::$name$(const $classname$* msg) {\n"
|
||||
" return *msg->$field_member$;\n"
|
||||
"}\n");
|
||||
}
|
||||
}
|
||||
|
||||
void MessageFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
|
||||
GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
|
||||
|
||||
Formatter format(printer, variables_);
|
||||
if (!HasFieldPresence(descriptor_->file())) {
|
||||
// If we don't have has-bits, message presence is indicated only by ptr !=
|
||||
// NULL. Thus on clear, we need to delete the object.
|
||||
format(
|
||||
"if (GetArena() == nullptr && $name$_ != nullptr) {\n"
|
||||
" delete $name$_;\n"
|
||||
"}\n"
|
||||
"$name$_ = nullptr;\n");
|
||||
} else {
|
||||
format("if ($name$_ != nullptr) $name$_->Clear();\n");
|
||||
}
|
||||
}
|
||||
|
||||
void MessageFieldGenerator::GenerateMessageClearingCode(
|
||||
io::Printer* printer) const {
|
||||
GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
|
||||
|
||||
Formatter format(printer, variables_);
|
||||
if (!HasFieldPresence(descriptor_->file())) {
|
||||
// If we don't have has-bits, message presence is indicated only by ptr !=
|
||||
// NULL. Thus on clear, we need to delete the object.
|
||||
format(
|
||||
"if (GetArena() == nullptr && $name$_ != nullptr) {\n"
|
||||
" delete $name$_;\n"
|
||||
"}\n"
|
||||
"$name$_ = nullptr;\n");
|
||||
} else {
|
||||
format(
|
||||
"$DCHK$($name$_ != nullptr);\n"
|
||||
"$name$_->Clear();\n");
|
||||
}
|
||||
}
|
||||
|
||||
void MessageFieldGenerator::GenerateMergingCode(io::Printer* printer) const {
|
||||
GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
|
||||
|
||||
Formatter format(printer, variables_);
|
||||
if (implicit_weak_field_) {
|
||||
format(
|
||||
"_Internal::mutable_$name$(this)->CheckTypeAndMergeFrom(\n"
|
||||
" _Internal::$name$(&from));\n");
|
||||
} else {
|
||||
format(
|
||||
"_internal_mutable_$name$()->$type$::MergeFrom(from._internal_$name$())"
|
||||
";\n");
|
||||
}
|
||||
}
|
||||
|
||||
void MessageFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
|
||||
GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
|
||||
|
||||
Formatter format(printer, variables_);
|
||||
format("swap($name$_, other->$name$_);\n");
|
||||
}
|
||||
|
||||
void MessageFieldGenerator::GenerateDestructorCode(io::Printer* printer) const {
|
||||
GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
|
||||
|
||||
Formatter format(printer, variables_);
|
||||
if (options_.opensource_runtime) {
|
||||
// TODO(gerbens) Remove this when we don't need to destruct default
|
||||
// instances. In google3 a default instance will never get deleted so we
|
||||
// don't need to worry about that but in opensource protobuf default
|
||||
// instances are deleted in shutdown process and we need to take special
|
||||
// care when handling them.
|
||||
format("if (this != internal_default_instance()) ");
|
||||
}
|
||||
format("delete $name$_;\n");
|
||||
}
|
||||
|
||||
void MessageFieldGenerator::GenerateConstructorCode(
|
||||
io::Printer* printer) const {
|
||||
GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
|
||||
|
||||
Formatter format(printer, variables_);
|
||||
format("$name$_ = nullptr;\n");
|
||||
}
|
||||
|
||||
void MessageFieldGenerator::GenerateCopyConstructorCode(
|
||||
io::Printer* printer) const {
|
||||
GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
|
||||
|
||||
Formatter format(printer, variables_);
|
||||
format(
|
||||
"if (from._internal_has_$name$()) {\n"
|
||||
" $name$_ = new $type$(*from.$name$_);\n"
|
||||
"} else {\n"
|
||||
" $name$_ = nullptr;\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
void MessageFieldGenerator::GenerateSerializeWithCachedSizesToArray(
|
||||
io::Printer* printer) const {
|
||||
GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
|
||||
|
||||
Formatter format(printer, variables_);
|
||||
format(
|
||||
"target = stream->EnsureSpace(target);\n"
|
||||
"target = ::$proto_ns$::internal::WireFormatLite::\n"
|
||||
" InternalWrite$declared_type$(\n"
|
||||
" $number$, _Internal::$name$(this), target, stream);\n");
|
||||
}
|
||||
|
||||
void MessageFieldGenerator::GenerateByteSize(io::Printer* printer) const {
|
||||
GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
|
||||
|
||||
Formatter format(printer, variables_);
|
||||
format(
|
||||
"total_size += $tag_size$ +\n"
|
||||
" ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n"
|
||||
" *$field_member$);\n");
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
|
||||
MessageOneofFieldGenerator::MessageOneofFieldGenerator(
|
||||
const FieldDescriptor* descriptor, const Options& options,
|
||||
MessageSCCAnalyzer* scc_analyzer)
|
||||
: MessageFieldGenerator(descriptor, options, scc_analyzer) {
|
||||
SetCommonOneofFieldVariables(descriptor, &variables_);
|
||||
}
|
||||
|
||||
MessageOneofFieldGenerator::~MessageOneofFieldGenerator() {}
|
||||
|
||||
void MessageOneofFieldGenerator::GenerateNonInlineAccessorDefinitions(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format(
|
||||
"void $classname$::set_allocated_$name$($type$* $name$) {\n"
|
||||
"$annotate_accessor$"
|
||||
" ::$proto_ns$::Arena* message_arena = GetArena();\n"
|
||||
" clear_$oneof_name$();\n"
|
||||
" if ($name$) {\n");
|
||||
if (descriptor_->file() != descriptor_->message_type()->file()) {
|
||||
// We have to read the arena through the virtual method, because the type
|
||||
// isn't defined in this file.
|
||||
format(
|
||||
" ::$proto_ns$::Arena* submessage_arena =\n"
|
||||
" "
|
||||
"reinterpret_cast<::$proto_ns$::MessageLite*>($name$)->GetArena();\n");
|
||||
} else {
|
||||
format(
|
||||
" ::$proto_ns$::Arena* submessage_arena =\n"
|
||||
" ::$proto_ns$::Arena::GetArena($name$);\n");
|
||||
}
|
||||
format(
|
||||
" if (message_arena != submessage_arena) {\n"
|
||||
" $name$ = ::$proto_ns$::internal::GetOwnedMessage(\n"
|
||||
" message_arena, $name$, submessage_arena);\n"
|
||||
" }\n"
|
||||
" set_has_$name$();\n"
|
||||
" $field_member$ = $name$;\n"
|
||||
" }\n"
|
||||
" // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
void MessageOneofFieldGenerator::GenerateInlineAccessorDefinitions(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format(
|
||||
"inline $type$* $classname$::$release_name$() {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_release:$full_name$)\n"
|
||||
" if (_internal_has_$name$()) {\n"
|
||||
" clear_has_$oneof_name$();\n"
|
||||
" $type$* temp = $field_member$;\n"
|
||||
" if (GetArena() != nullptr) {\n"
|
||||
" temp = ::$proto_ns$::internal::DuplicateIfNonNull(temp);\n"
|
||||
" }\n"
|
||||
" $field_member$ = nullptr;\n"
|
||||
" return temp;\n"
|
||||
" } else {\n"
|
||||
" return nullptr;\n"
|
||||
" }\n"
|
||||
"}\n");
|
||||
|
||||
format(
|
||||
"inline const $type$& $classname$::_internal_$name$() const {\n"
|
||||
" return _internal_has_$name$()\n"
|
||||
" ? *$field_member$\n"
|
||||
" : reinterpret_cast< $type$&>($type_default_instance$);\n"
|
||||
"}\n"
|
||||
"inline const $type$& $classname$::$name$() const {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_get:$full_name$)\n"
|
||||
" return _internal_$name$();\n"
|
||||
"}\n"
|
||||
"inline $type$* $classname$::unsafe_arena_release_$name$() {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_unsafe_arena_release"
|
||||
":$full_name$)\n"
|
||||
" if (_internal_has_$name$()) {\n"
|
||||
" clear_has_$oneof_name$();\n"
|
||||
" $type$* temp = $field_member$;\n"
|
||||
" $field_member$ = nullptr;\n"
|
||||
" return temp;\n"
|
||||
" } else {\n"
|
||||
" return nullptr;\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"inline void $classname$::unsafe_arena_set_allocated_$name$"
|
||||
"($type$* $name$) {\n"
|
||||
"$annotate_accessor$"
|
||||
// We rely on the oneof clear method to free the earlier contents of
|
||||
// this oneof. We can directly use the pointer we're given to set the
|
||||
// new value.
|
||||
" clear_$oneof_name$();\n"
|
||||
" if ($name$) {\n"
|
||||
" set_has_$name$();\n"
|
||||
" $field_member$ = $name$;\n"
|
||||
" }\n"
|
||||
" // @@protoc_insertion_point(field_unsafe_arena_set_allocated:"
|
||||
"$full_name$)\n"
|
||||
"}\n"
|
||||
"inline $type$* $classname$::_internal_mutable_$name$() {\n"
|
||||
" if (!_internal_has_$name$()) {\n"
|
||||
" clear_$oneof_name$();\n"
|
||||
" set_has_$name$();\n"
|
||||
" $field_member$ = CreateMaybeMessage< $type$ >(GetArena());\n"
|
||||
" }\n"
|
||||
" return $field_member$;\n"
|
||||
"}\n"
|
||||
"inline $type$* $classname$::mutable_$name$() {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_mutable:$full_name$)\n"
|
||||
" return _internal_mutable_$name$();\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
void MessageOneofFieldGenerator::GenerateClearingCode(
|
||||
io::Printer* printer) const {
|
||||
GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
|
||||
|
||||
Formatter format(printer, variables_);
|
||||
format(
|
||||
"if (GetArena() == nullptr) {\n"
|
||||
" delete $field_member$;\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
void MessageOneofFieldGenerator::GenerateMessageClearingCode(
|
||||
io::Printer* printer) const {
|
||||
GenerateClearingCode(printer);
|
||||
}
|
||||
|
||||
void MessageOneofFieldGenerator::GenerateSwappingCode(
|
||||
io::Printer* printer) const {
|
||||
// Don't print any swapping code. Swapping the union will swap this field.
|
||||
}
|
||||
|
||||
void MessageOneofFieldGenerator::GenerateDestructorCode(
|
||||
io::Printer* printer) const {
|
||||
// We inherit from MessageFieldGenerator, so we need to override the default
|
||||
// behavior.
|
||||
}
|
||||
|
||||
void MessageOneofFieldGenerator::GenerateConstructorCode(
|
||||
io::Printer* printer) const {
|
||||
// Don't print any constructor code. The field is in a union. We allocate
|
||||
// space only when this field is used.
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
|
||||
RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator(
|
||||
const FieldDescriptor* descriptor, const Options& options,
|
||||
MessageSCCAnalyzer* scc_analyzer)
|
||||
: FieldGenerator(descriptor, options),
|
||||
implicit_weak_field_(
|
||||
IsImplicitWeakField(descriptor, options, scc_analyzer)) {
|
||||
SetMessageVariables(descriptor, options, implicit_weak_field_, &variables_);
|
||||
}
|
||||
|
||||
RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
|
||||
|
||||
void RepeatedMessageFieldGenerator::GeneratePrivateMembers(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
if (implicit_weak_field_) {
|
||||
format("::$proto_ns$::WeakRepeatedPtrField< $type$ > $name$_;\n");
|
||||
} else {
|
||||
format("::$proto_ns$::RepeatedPtrField< $type$ > $name$_;\n");
|
||||
}
|
||||
}
|
||||
|
||||
void RepeatedMessageFieldGenerator::GenerateAccessorDeclarations(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
if (IsFieldStripped(descriptor_, options_)) {
|
||||
format(
|
||||
"$deprecated_attr$$type$* ${1$mutable_$name$$}$(int index) { "
|
||||
"__builtin_trap(); }\n"
|
||||
"$deprecated_attr$::$proto_ns$::RepeatedPtrField< $type$ >*\n"
|
||||
" ${1$mutable_$name$$}$() { __builtin_trap(); }\n"
|
||||
"$deprecated_attr$const $type$& ${1$$name$$}$(int index) const { "
|
||||
"__builtin_trap(); }\n"
|
||||
"$deprecated_attr$$type$* ${1$add_$name$$}$() { "
|
||||
"__builtin_trap(); }\n"
|
||||
"$deprecated_attr$const ::$proto_ns$::RepeatedPtrField< $type$ >&\n"
|
||||
" ${1$$name$$}$() const { __builtin_trap(); }\n",
|
||||
descriptor_);
|
||||
return;
|
||||
}
|
||||
format(
|
||||
"$deprecated_attr$$type$* ${1$mutable_$name$$}$(int index);\n"
|
||||
"$deprecated_attr$::$proto_ns$::RepeatedPtrField< $type$ >*\n"
|
||||
" ${1$mutable_$name$$}$();\n",
|
||||
descriptor_);
|
||||
if (!IsFieldStripped(descriptor_, options_)) {
|
||||
format(
|
||||
"private:\n"
|
||||
"const $type$& ${1$_internal_$name$$}$(int index) const;\n"
|
||||
"$type$* ${1$_internal_add_$name$$}$();\n"
|
||||
"public:\n",
|
||||
descriptor_);
|
||||
}
|
||||
format(
|
||||
"$deprecated_attr$const $type$& ${1$$name$$}$(int index) const;\n"
|
||||
"$deprecated_attr$$type$* ${1$add_$name$$}$();\n"
|
||||
"$deprecated_attr$const ::$proto_ns$::RepeatedPtrField< $type$ >&\n"
|
||||
" ${1$$name$$}$() const;\n",
|
||||
descriptor_);
|
||||
}
|
||||
|
||||
void RepeatedMessageFieldGenerator::GenerateInlineAccessorDefinitions(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format.Set("weak", implicit_weak_field_ ? ".weak" : "");
|
||||
|
||||
format(
|
||||
"inline $type$* $classname$::mutable_$name$(int index) {\n"
|
||||
"$annotate_accessor$"
|
||||
// TODO(dlj): move insertion points
|
||||
" // @@protoc_insertion_point(field_mutable:$full_name$)\n"
|
||||
"$type_reference_function$"
|
||||
" return $name$_$weak$.Mutable(index);\n"
|
||||
"}\n"
|
||||
"inline ::$proto_ns$::RepeatedPtrField< $type$ >*\n"
|
||||
"$classname$::mutable_$name$() {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
|
||||
"$type_reference_function$"
|
||||
" return &$name$_$weak$;\n"
|
||||
"}\n");
|
||||
|
||||
if (options_.safe_boundary_check) {
|
||||
format(
|
||||
"inline const $type$& $classname$::_internal_$name$(int index) const "
|
||||
"{\n"
|
||||
" return $name$_$weak$.InternalCheckedGet(index,\n"
|
||||
" reinterpret_cast<const $type$&>($type_default_instance$));\n"
|
||||
"}\n");
|
||||
} else {
|
||||
format(
|
||||
"inline const $type$& $classname$::_internal_$name$(int index) const "
|
||||
"{\n"
|
||||
"$type_reference_function$"
|
||||
" return $name$_$weak$.Get(index);\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
format(
|
||||
"inline const $type$& $classname$::$name$(int index) const {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_get:$full_name$)\n"
|
||||
" return _internal_$name$(index);\n"
|
||||
"}\n"
|
||||
"inline $type$* $classname$::_internal_add_$name$() {\n"
|
||||
" return $name$_$weak$.Add();\n"
|
||||
"}\n"
|
||||
"inline $type$* $classname$::add_$name$() {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_add:$full_name$)\n"
|
||||
" return _internal_add_$name$();\n"
|
||||
"}\n");
|
||||
|
||||
format(
|
||||
"inline const ::$proto_ns$::RepeatedPtrField< $type$ >&\n"
|
||||
"$classname$::$name$() const {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_list:$full_name$)\n"
|
||||
"$type_reference_function$"
|
||||
" return $name$_$weak$;\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
void RepeatedMessageFieldGenerator::GenerateClearingCode(
|
||||
io::Printer* printer) const {
|
||||
GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
|
||||
|
||||
Formatter format(printer, variables_);
|
||||
format("$name$_.Clear();\n");
|
||||
}
|
||||
|
||||
void RepeatedMessageFieldGenerator::GenerateMergingCode(
|
||||
io::Printer* printer) const {
|
||||
GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
|
||||
|
||||
Formatter format(printer, variables_);
|
||||
format("$name$_.MergeFrom(from.$name$_);\n");
|
||||
}
|
||||
|
||||
void RepeatedMessageFieldGenerator::GenerateSwappingCode(
|
||||
io::Printer* printer) const {
|
||||
GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
|
||||
|
||||
Formatter format(printer, variables_);
|
||||
format("$name$_.InternalSwap(&other->$name$_);\n");
|
||||
}
|
||||
|
||||
void RepeatedMessageFieldGenerator::GenerateConstructorCode(
|
||||
io::Printer* printer) const {
|
||||
// Not needed for repeated fields.
|
||||
}
|
||||
|
||||
void RepeatedMessageFieldGenerator::GenerateSerializeWithCachedSizesToArray(
|
||||
io::Printer* printer) const {
|
||||
GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
|
||||
|
||||
Formatter format(printer, variables_);
|
||||
if (implicit_weak_field_) {
|
||||
format(
|
||||
"for (auto it = this->$name$_.pointer_begin(),\n"
|
||||
" end = this->$name$_.pointer_end(); it < end; ++it) {\n"
|
||||
" target = stream->EnsureSpace(target);\n"
|
||||
" target = ::$proto_ns$::internal::WireFormatLite::\n"
|
||||
" InternalWrite$declared_type$($number$, **it, target, stream);\n"
|
||||
"}\n");
|
||||
} else {
|
||||
format(
|
||||
"for (unsigned int i = 0,\n"
|
||||
" n = static_cast<unsigned int>(this->_internal_$name$_size()); i < "
|
||||
"n; i++) "
|
||||
"{\n"
|
||||
" target = stream->EnsureSpace(target);\n"
|
||||
" target = ::$proto_ns$::internal::WireFormatLite::\n"
|
||||
" InternalWrite$declared_type$($number$, "
|
||||
"this->_internal_$name$(i), target, stream);\n"
|
||||
"}\n");
|
||||
}
|
||||
}
|
||||
|
||||
void RepeatedMessageFieldGenerator::GenerateByteSize(
|
||||
io::Printer* printer) const {
|
||||
GOOGLE_CHECK(!IsFieldStripped(descriptor_, options_));
|
||||
|
||||
Formatter format(printer, variables_);
|
||||
format(
|
||||
"total_size += $tag_size$UL * this->_internal_$name$_size();\n"
|
||||
"for (const auto& msg : this->$name$_) {\n"
|
||||
" total_size +=\n"
|
||||
" ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(msg);\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
132
ubuntu/google/protobuf/compiler/cpp/cpp_message_field.h
Normal file
132
ubuntu/google/protobuf/compiler/cpp/cpp_message_field.h
Normal file
@@ -0,0 +1,132 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// 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>
|
||||
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace cpp {
|
||||
|
||||
class MessageFieldGenerator : public FieldGenerator {
|
||||
public:
|
||||
MessageFieldGenerator(const FieldDescriptor* descriptor,
|
||||
const Options& options,
|
||||
MessageSCCAnalyzer* scc_analyzer);
|
||||
~MessageFieldGenerator();
|
||||
|
||||
// implements FieldGenerator ---------------------------------------
|
||||
void GeneratePrivateMembers(io::Printer* printer) const;
|
||||
void GenerateAccessorDeclarations(io::Printer* printer) const;
|
||||
void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
|
||||
void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const;
|
||||
void GenerateInternalAccessorDeclarations(io::Printer* printer) const;
|
||||
void GenerateInternalAccessorDefinitions(io::Printer* printer) const;
|
||||
void GenerateClearingCode(io::Printer* printer) const;
|
||||
void GenerateMessageClearingCode(io::Printer* printer) const;
|
||||
void GenerateMergingCode(io::Printer* printer) const;
|
||||
void GenerateSwappingCode(io::Printer* printer) const;
|
||||
void GenerateDestructorCode(io::Printer* printer) const;
|
||||
void GenerateConstructorCode(io::Printer* printer) const;
|
||||
void GenerateCopyConstructorCode(io::Printer* printer) const;
|
||||
void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
|
||||
void GenerateByteSize(io::Printer* printer) const;
|
||||
|
||||
protected:
|
||||
const bool implicit_weak_field_;
|
||||
|
||||
private:
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator);
|
||||
};
|
||||
|
||||
class MessageOneofFieldGenerator : public MessageFieldGenerator {
|
||||
public:
|
||||
MessageOneofFieldGenerator(const FieldDescriptor* descriptor,
|
||||
const Options& options,
|
||||
MessageSCCAnalyzer* scc_analyzer);
|
||||
~MessageOneofFieldGenerator();
|
||||
|
||||
// implements FieldGenerator ---------------------------------------
|
||||
void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
|
||||
void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const;
|
||||
void GenerateClearingCode(io::Printer* printer) const;
|
||||
|
||||
// MessageFieldGenerator, from which we inherit, overrides this so we need to
|
||||
// override it as well.
|
||||
void GenerateMessageClearingCode(io::Printer* printer) const;
|
||||
void GenerateSwappingCode(io::Printer* printer) const;
|
||||
void GenerateDestructorCode(io::Printer* printer) const;
|
||||
void GenerateConstructorCode(io::Printer* printer) const;
|
||||
|
||||
private:
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageOneofFieldGenerator);
|
||||
};
|
||||
|
||||
class RepeatedMessageFieldGenerator : public FieldGenerator {
|
||||
public:
|
||||
RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor,
|
||||
const Options& options,
|
||||
MessageSCCAnalyzer* scc_analyzer);
|
||||
~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 GenerateCopyConstructorCode(io::Printer* printer) const {}
|
||||
void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
|
||||
void GenerateByteSize(io::Printer* printer) const;
|
||||
|
||||
private:
|
||||
const bool implicit_weak_field_;
|
||||
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator);
|
||||
};
|
||||
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_FIELD_H__
|
||||
@@ -0,0 +1,61 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Author: seongkim@google.com (Seong Beom Kim)
|
||||
// Based on original Protocol Buffers design by
|
||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_LAYOUT_HELPER_H__
|
||||
#define GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_LAYOUT_HELPER_H__
|
||||
|
||||
#include <google/protobuf/compiler/cpp/cpp_options.h>
|
||||
#include <google/protobuf/descriptor.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace cpp {
|
||||
|
||||
// Provides an abstract interface to optimize message layout
|
||||
// by rearranging the fields of a message.
|
||||
class MessageLayoutHelper {
|
||||
public:
|
||||
virtual ~MessageLayoutHelper() {}
|
||||
|
||||
virtual void OptimizeLayout(std::vector<const FieldDescriptor*>* fields,
|
||||
const Options& options) = 0;
|
||||
};
|
||||
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_CPP_MESSAGE_LAYOUT_HELPER_H__
|
||||
169
ubuntu/google/protobuf/compiler/cpp/cpp_move_unittest.cc
Normal file
169
ubuntu/google/protobuf/compiler/cpp/cpp_move_unittest.cc
Normal file
@@ -0,0 +1,169 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
#include <google/protobuf/test_util.h>
|
||||
#include <google/protobuf/unittest.pb.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#if LANG_CXX11
|
||||
#include <type_traits>
|
||||
#endif
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace cpp {
|
||||
|
||||
// Can't use an anonymous namespace here due to brokenness of Tru64 compiler.
|
||||
namespace cpp_unittest {
|
||||
|
||||
// Moves are enabled only when compiling with a C++11 compiler or newer.
|
||||
#if LANG_CXX11
|
||||
|
||||
TEST(MovableMessageTest, MoveConstructor) {
|
||||
protobuf_unittest::TestAllTypes message1;
|
||||
TestUtil::SetAllFields(&message1);
|
||||
const auto* nested = &message1.optional_nested_message();
|
||||
|
||||
protobuf_unittest::TestAllTypes message2(std::move(message1));
|
||||
TestUtil::ExpectAllFieldsSet(message2);
|
||||
|
||||
// Check if the optional_nested_message was actually moved (and not just
|
||||
// copied).
|
||||
EXPECT_EQ(nested, &message2.optional_nested_message());
|
||||
EXPECT_NE(nested, &message1.optional_nested_message());
|
||||
}
|
||||
|
||||
TEST(MovableMessageTest, MoveAssignmentOperator) {
|
||||
protobuf_unittest::TestAllTypes message1;
|
||||
TestUtil::SetAllFields(&message1);
|
||||
const auto* nested = &message1.optional_nested_message();
|
||||
|
||||
protobuf_unittest::TestAllTypes message2;
|
||||
message2 = std::move(message1);
|
||||
TestUtil::ExpectAllFieldsSet(message2);
|
||||
|
||||
// Check if the optional_nested_message was actually moved (and not just
|
||||
// copied).
|
||||
EXPECT_EQ(nested, &message2.optional_nested_message());
|
||||
EXPECT_NE(nested, &message1.optional_nested_message());
|
||||
}
|
||||
|
||||
TEST(MovableMessageTest, SelfMoveAssignment) {
|
||||
// The `self` reference is necessary to defeat -Wself-move.
|
||||
protobuf_unittest::TestAllTypes message, &self = message;
|
||||
TestUtil::SetAllFields(&message);
|
||||
message = std::move(self);
|
||||
TestUtil::ExpectAllFieldsSet(message);
|
||||
}
|
||||
|
||||
TEST(MovableMessageTest, MoveSameArena) {
|
||||
Arena arena;
|
||||
|
||||
auto* message1_on_arena =
|
||||
Arena::CreateMessage<protobuf_unittest::TestAllTypes>(&arena);
|
||||
TestUtil::SetAllFields(message1_on_arena);
|
||||
const auto* nested = &message1_on_arena->optional_nested_message();
|
||||
|
||||
auto* message2_on_arena =
|
||||
Arena::CreateMessage<protobuf_unittest::TestAllTypes>(&arena);
|
||||
|
||||
// Moving messages on the same arena should lead to swapped pointers.
|
||||
*message2_on_arena = std::move(*message1_on_arena);
|
||||
EXPECT_EQ(nested, &message2_on_arena->optional_nested_message());
|
||||
}
|
||||
|
||||
TEST(MovableMessageTest, MoveDifferentArenas) {
|
||||
Arena arena1, arena2;
|
||||
|
||||
auto* message1_on_arena =
|
||||
Arena::CreateMessage<protobuf_unittest::TestAllTypes>(&arena1);
|
||||
TestUtil::SetAllFields(message1_on_arena);
|
||||
const auto* nested = &message1_on_arena->optional_nested_message();
|
||||
|
||||
auto* message2_on_arena =
|
||||
Arena::CreateMessage<protobuf_unittest::TestAllTypes>(&arena2);
|
||||
|
||||
// Moving messages on two different arenas should lead to a copy.
|
||||
*message2_on_arena = std::move(*message1_on_arena);
|
||||
EXPECT_NE(nested, &message2_on_arena->optional_nested_message());
|
||||
TestUtil::ExpectAllFieldsSet(*message1_on_arena);
|
||||
TestUtil::ExpectAllFieldsSet(*message2_on_arena);
|
||||
}
|
||||
|
||||
TEST(MovableMessageTest, MoveFromArena) {
|
||||
Arena arena;
|
||||
|
||||
auto* message1_on_arena =
|
||||
Arena::CreateMessage<protobuf_unittest::TestAllTypes>(&arena);
|
||||
TestUtil::SetAllFields(message1_on_arena);
|
||||
const auto* nested = &message1_on_arena->optional_nested_message();
|
||||
|
||||
protobuf_unittest::TestAllTypes message2;
|
||||
|
||||
// Moving from a message on the arena should lead to a copy.
|
||||
message2 = std::move(*message1_on_arena);
|
||||
EXPECT_NE(nested, &message2.optional_nested_message());
|
||||
TestUtil::ExpectAllFieldsSet(*message1_on_arena);
|
||||
TestUtil::ExpectAllFieldsSet(message2);
|
||||
}
|
||||
|
||||
TEST(MovableMessageTest, MoveToArena) {
|
||||
Arena arena;
|
||||
|
||||
protobuf_unittest::TestAllTypes message1;
|
||||
TestUtil::SetAllFields(&message1);
|
||||
const auto* nested = &message1.optional_nested_message();
|
||||
|
||||
auto* message2_on_arena =
|
||||
Arena::CreateMessage<protobuf_unittest::TestAllTypes>(&arena);
|
||||
|
||||
// Moving to a message on the arena should lead to a copy.
|
||||
*message2_on_arena = std::move(message1);
|
||||
EXPECT_NE(nested, &message2_on_arena->optional_nested_message());
|
||||
TestUtil::ExpectAllFieldsSet(message1);
|
||||
TestUtil::ExpectAllFieldsSet(*message2_on_arena);
|
||||
}
|
||||
|
||||
TEST(MovableMessageTest, Noexcept) {
|
||||
EXPECT_TRUE(
|
||||
std::is_nothrow_move_constructible<protobuf_unittest::TestAllTypes>());
|
||||
EXPECT_TRUE(std::is_nothrow_move_assignable<protobuf_unittest::TestAllTypes>());
|
||||
}
|
||||
|
||||
#endif // LANG_CXX11
|
||||
|
||||
} // namespace cpp_unittest
|
||||
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
79
ubuntu/google/protobuf/compiler/cpp/cpp_options.h
Normal file
79
ubuntu/google/protobuf/compiler/cpp/cpp_options.h
Normal file
@@ -0,0 +1,79 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Author: rennie@google.com (Jeffrey Rennie)
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_OPTIONS_H__
|
||||
#define GOOGLE_PROTOBUF_COMPILER_CPP_OPTIONS_H__
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
class AccessInfoMap;
|
||||
|
||||
namespace cpp {
|
||||
|
||||
enum class EnforceOptimizeMode {
|
||||
kNoEnforcement, // Use the runtime specified by the file specific options.
|
||||
kSpeed, // Full runtime with a generated code implementation.
|
||||
kCodeSize, // Full runtime with a reflective implementation.
|
||||
kLiteRuntime,
|
||||
};
|
||||
|
||||
// Generator options (see generator.cc for a description of each):
|
||||
struct Options {
|
||||
std::string dllexport_decl;
|
||||
bool safe_boundary_check = false;
|
||||
bool proto_h = false;
|
||||
bool transitive_pb_h = true;
|
||||
bool annotate_headers = false;
|
||||
EnforceOptimizeMode enforce_mode = EnforceOptimizeMode::kNoEnforcement;
|
||||
bool table_driven_parsing = false;
|
||||
bool table_driven_serialization = false;
|
||||
bool lite_implicit_weak_fields = false;
|
||||
bool bootstrap = false;
|
||||
bool opensource_runtime = false;
|
||||
bool annotate_accessor = false;
|
||||
bool unused_field_stripping = false;
|
||||
std::string runtime_include_base;
|
||||
int num_cc_files = 0;
|
||||
std::string annotation_pragma_name;
|
||||
std::string annotation_guard_name;
|
||||
const AccessInfoMap* access_info_map = nullptr;
|
||||
};
|
||||
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_CPP_OPTIONS_H__
|
||||
227
ubuntu/google/protobuf/compiler/cpp/cpp_padding_optimizer.cc
Normal file
227
ubuntu/google/protobuf/compiler/cpp/cpp_padding_optimizer.cc
Normal file
@@ -0,0 +1,227 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <google/protobuf/compiler/cpp/cpp_padding_optimizer.h>
|
||||
|
||||
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace cpp {
|
||||
|
||||
namespace {
|
||||
|
||||
// FieldGroup is just a helper for PaddingOptimizer below. It holds a vector of
|
||||
// fields that are grouped together because they have compatible alignment, and
|
||||
// a preferred location in the final field ordering.
|
||||
class FieldGroup {
|
||||
public:
|
||||
FieldGroup() : preferred_location_(0) {}
|
||||
|
||||
// A group with a single field.
|
||||
FieldGroup(float preferred_location, const FieldDescriptor* field)
|
||||
: preferred_location_(preferred_location), fields_(1, field) {}
|
||||
|
||||
// Append the fields in 'other' to this group.
|
||||
void Append(const FieldGroup& other) {
|
||||
if (other.fields_.empty()) {
|
||||
return;
|
||||
}
|
||||
// Preferred location is the average among all the fields, so we weight by
|
||||
// the number of fields on each FieldGroup object.
|
||||
preferred_location_ = (preferred_location_ * fields_.size() +
|
||||
(other.preferred_location_ * other.fields_.size())) /
|
||||
(fields_.size() + other.fields_.size());
|
||||
fields_.insert(fields_.end(), other.fields_.begin(), other.fields_.end());
|
||||
}
|
||||
|
||||
void SetPreferredLocation(float location) { preferred_location_ = location; }
|
||||
const std::vector<const FieldDescriptor*>& fields() const { return fields_; }
|
||||
|
||||
// FieldGroup objects sort by their preferred location.
|
||||
bool operator<(const FieldGroup& other) const {
|
||||
return preferred_location_ < other.preferred_location_;
|
||||
}
|
||||
|
||||
private:
|
||||
// "preferred_location_" is an estimate of where this group should go in the
|
||||
// final list of fields. We compute this by taking the average index of each
|
||||
// field in this group in the original ordering of fields. This is very
|
||||
// approximate, but should put this group close to where its member fields
|
||||
// originally went.
|
||||
float preferred_location_;
|
||||
std::vector<const FieldDescriptor*> fields_;
|
||||
// We rely on the default copy constructor and operator= so this type can be
|
||||
// used in a vector.
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
// Reorder 'fields' so that if the fields are output into a c++ class in the new
|
||||
// order, fields of similar family (see below) are together and within each
|
||||
// family, alignment padding is minimized.
|
||||
//
|
||||
// We try to do this while keeping each field as close as possible to its field
|
||||
// number order so that we don't reduce cache locality much for function that
|
||||
// access each field in order. Originally, OptimizePadding used declaration
|
||||
// order for its decisions, but generated code minus the serializer/parsers uses
|
||||
// the output of OptimizePadding as well (stored in
|
||||
// MessageGenerator::optimized_order_). Since the serializers use field number
|
||||
// order, we use that as a tie-breaker.
|
||||
//
|
||||
// We classify each field into a particular "family" of fields, that we perform
|
||||
// the same operation on in our generated functions.
|
||||
//
|
||||
// REPEATED is placed first, as the C++ compiler automatically initializes
|
||||
// these fields in layout order.
|
||||
//
|
||||
// STRING is grouped next, as our Clear/SharedCtor/SharedDtor walks it and
|
||||
// calls ArenaStringPtr::Destroy on each.
|
||||
//
|
||||
// LAZY_MESSAGE is grouped next, as it interferes with the ability to memset
|
||||
// non-repeated fields otherwise.
|
||||
//
|
||||
// MESSAGE is grouped next, as our Clear/SharedDtor code walks it and calls
|
||||
// delete on each. We initialize these fields with a NULL pointer (see
|
||||
// MessageFieldGenerator::GenerateConstructorCode), which allows them to be
|
||||
// memset.
|
||||
//
|
||||
// ZERO_INITIALIZABLE is memset in Clear/SharedCtor
|
||||
//
|
||||
// OTHER these fields are initialized one-by-one.
|
||||
void PaddingOptimizer::OptimizeLayout(
|
||||
std::vector<const FieldDescriptor*>* fields, const Options& options) {
|
||||
// The sorted numeric order of Family determines the declaration order in the
|
||||
// memory layout.
|
||||
enum Family {
|
||||
REPEATED = 0,
|
||||
STRING = 1,
|
||||
// Laying out LAZY_MESSAGE before MESSAGE allows a single memset to zero
|
||||
// MESSAGE and ZERO_INITIALIZABLE fields together.
|
||||
LAZY_MESSAGE = 2,
|
||||
MESSAGE = 3,
|
||||
ZERO_INITIALIZABLE = 4,
|
||||
OTHER = 5,
|
||||
kMaxFamily
|
||||
};
|
||||
|
||||
// First divide fields into those that align to 1 byte, 4 bytes or 8 bytes.
|
||||
std::vector<FieldGroup> aligned_to_1[kMaxFamily];
|
||||
std::vector<FieldGroup> aligned_to_4[kMaxFamily];
|
||||
std::vector<FieldGroup> aligned_to_8[kMaxFamily];
|
||||
for (int i = 0; i < fields->size(); ++i) {
|
||||
const FieldDescriptor* field = (*fields)[i];
|
||||
|
||||
Family f = OTHER;
|
||||
if (field->is_repeated()) {
|
||||
f = REPEATED;
|
||||
} else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
|
||||
f = STRING;
|
||||
} else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
|
||||
f = MESSAGE;
|
||||
if (IsLazy(field, options)) {
|
||||
f = LAZY_MESSAGE;
|
||||
}
|
||||
} else if (CanInitializeByZeroing(field)) {
|
||||
f = ZERO_INITIALIZABLE;
|
||||
}
|
||||
|
||||
const int j = field->number();
|
||||
switch (EstimateAlignmentSize(field)) {
|
||||
case 1:
|
||||
aligned_to_1[f].push_back(FieldGroup(j, field));
|
||||
break;
|
||||
case 4:
|
||||
aligned_to_4[f].push_back(FieldGroup(j, field));
|
||||
break;
|
||||
case 8:
|
||||
aligned_to_8[f].push_back(FieldGroup(j, field));
|
||||
break;
|
||||
default:
|
||||
GOOGLE_LOG(FATAL) << "Unknown alignment size " << EstimateAlignmentSize(field)
|
||||
<< "for a field " << field->full_name() << ".";
|
||||
}
|
||||
}
|
||||
|
||||
// For each family, group fields to optimize padding.
|
||||
for (int f = 0; f < kMaxFamily; f++) {
|
||||
// Now group fields aligned to 1 byte into sets of 4, and treat those like a
|
||||
// single field aligned to 4 bytes.
|
||||
for (int i = 0; i < aligned_to_1[f].size(); i += 4) {
|
||||
FieldGroup field_group;
|
||||
for (int j = i; j < aligned_to_1[f].size() && j < i + 4; ++j) {
|
||||
field_group.Append(aligned_to_1[f][j]);
|
||||
}
|
||||
aligned_to_4[f].push_back(field_group);
|
||||
}
|
||||
// Sort by preferred location to keep fields as close to their field number
|
||||
// order as possible. Using stable_sort ensures that the output is
|
||||
// consistent across runs.
|
||||
std::stable_sort(aligned_to_4[f].begin(), aligned_to_4[f].end());
|
||||
|
||||
// Now group fields aligned to 4 bytes (or the 4-field groups created above)
|
||||
// into pairs, and treat those like a single field aligned to 8 bytes.
|
||||
for (int i = 0; i < aligned_to_4[f].size(); i += 2) {
|
||||
FieldGroup field_group;
|
||||
for (int j = i; j < aligned_to_4[f].size() && j < i + 2; ++j) {
|
||||
field_group.Append(aligned_to_4[f][j]);
|
||||
}
|
||||
if (i == aligned_to_4[f].size() - 1) {
|
||||
if (f == OTHER) {
|
||||
// Move incomplete 4-byte block to the beginning. This is done to
|
||||
// pair with the (possible) leftover blocks from the
|
||||
// ZERO_INITIALIZABLE family.
|
||||
field_group.SetPreferredLocation(-1);
|
||||
} else {
|
||||
// Move incomplete 4-byte block to the end.
|
||||
field_group.SetPreferredLocation(fields->size() + 1);
|
||||
}
|
||||
}
|
||||
aligned_to_8[f].push_back(field_group);
|
||||
}
|
||||
// Sort by preferred location.
|
||||
std::stable_sort(aligned_to_8[f].begin(), aligned_to_8[f].end());
|
||||
}
|
||||
|
||||
// Now pull out all the FieldDescriptors in order.
|
||||
fields->clear();
|
||||
for (int f = 0; f < kMaxFamily; ++f) {
|
||||
for (int i = 0; i < aligned_to_8[f].size(); ++i) {
|
||||
fields->insert(fields->end(), aligned_to_8[f][i].fields().begin(),
|
||||
aligned_to_8[f][i].fields().end());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
64
ubuntu/google/protobuf/compiler/cpp/cpp_padding_optimizer.h
Normal file
64
ubuntu/google/protobuf/compiler/cpp/cpp_padding_optimizer.h
Normal file
@@ -0,0 +1,64 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Author: seongkim@google.com (Seong Beom Kim)
|
||||
// Based on original Protocol Buffers design by
|
||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_PADDING_OPTIMIZER_H__
|
||||
#define GOOGLE_PROTOBUF_COMPILER_CPP_PADDING_OPTIMIZER_H__
|
||||
|
||||
#include <google/protobuf/compiler/cpp/cpp_message_layout_helper.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace cpp {
|
||||
|
||||
// Rearranges the fields of a message to minimize padding.
|
||||
// Fields are grouped by the type and the size.
|
||||
// For example, grouping four boolean fields and one int32
|
||||
// field results in zero padding overhead. See OptimizeLayout's
|
||||
// comment for details.
|
||||
class PaddingOptimizer : public MessageLayoutHelper {
|
||||
public:
|
||||
PaddingOptimizer() {}
|
||||
~PaddingOptimizer() override {}
|
||||
|
||||
void OptimizeLayout(std::vector<const FieldDescriptor*>* fields,
|
||||
const Options& options) override;
|
||||
};
|
||||
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_CPP_PADDING_OPTIMIZER_H__
|
||||
245
ubuntu/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
Normal file
245
ubuntu/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
Normal file
@@ -0,0 +1,245 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Author: kenton@google.com (Kenton Varda)
|
||||
//
|
||||
// TODO(kenton): Share code with the versions of this test in other languages?
|
||||
// It seemed like parameterizing it would add more complexity than it is
|
||||
// worth.
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <google/protobuf/compiler/cpp/cpp_generator.h>
|
||||
#include <google/protobuf/compiler/command_line_interface.h>
|
||||
#include <google/protobuf/io/printer.h>
|
||||
#include <google/protobuf/io/zero_copy_stream.h>
|
||||
|
||||
#include <google/protobuf/testing/file.h>
|
||||
#include <google/protobuf/testing/file.h>
|
||||
#include <google/protobuf/testing/googletest.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace cpp {
|
||||
namespace {
|
||||
|
||||
class TestGenerator : public CodeGenerator {
|
||||
public:
|
||||
TestGenerator() {}
|
||||
~TestGenerator() {}
|
||||
|
||||
virtual bool Generate(const FileDescriptor* file,
|
||||
const std::string& parameter, GeneratorContext* context,
|
||||
std::string* error) const {
|
||||
TryInsert("test.pb.h", "includes", context);
|
||||
TryInsert("test.pb.h", "namespace_scope", context);
|
||||
TryInsert("test.pb.h", "global_scope", context);
|
||||
TryInsert("test.pb.h", "class_scope:foo.Bar", context);
|
||||
TryInsert("test.pb.h", "class_scope:foo.Bar.Baz", context);
|
||||
|
||||
TryInsert("test.pb.cc", "includes", context);
|
||||
TryInsert("test.pb.cc", "namespace_scope", context);
|
||||
TryInsert("test.pb.cc", "global_scope", context);
|
||||
|
||||
// Check field accessors for an optional int32:
|
||||
TryInsert("test.pb.h", "field_get:foo.Bar.optInt", context);
|
||||
TryInsert("test.pb.h", "field_set:foo.Bar.optInt", context);
|
||||
|
||||
// Check field accessors for a repeated int32:
|
||||
TryInsert("test.pb.h", "field_get:foo.Bar.repeatedInt", context);
|
||||
TryInsert("test.pb.h", "field_set:foo.Bar.repeatedInt", context);
|
||||
|
||||
// Check field accessors for a required string:
|
||||
TryInsert("test.pb.h", "field_get:foo.Bar.requiredString", context);
|
||||
TryInsert("test.pb.h", "field_set:foo.Bar.requiredString", context);
|
||||
TryInsert("test.pb.h", "field_set_char:foo.Bar.requiredString", context);
|
||||
TryInsert("test.pb.h", "field_set_pointer:foo.Bar.requiredString", context);
|
||||
TryInsert("test.pb.h", "field_mutable:foo.Bar.requiredString", context);
|
||||
TryInsert("test.pb.h", "field_set_allocated:foo.Bar.requiredString",
|
||||
context);
|
||||
TryInsert("test.pb.h", "field_set_char:foo.Bar.requiredString", context);
|
||||
TryInsert("test.pb.h", "field_set_pointer:foo.Bar.requiredString", context);
|
||||
|
||||
// Check field accessors for a repeated string:
|
||||
TryInsert("test.pb.h", "field_get:foo.Bar.repeatedString", context);
|
||||
TryInsert("test.pb.h", "field_set:foo.Bar.repeatedString", context);
|
||||
TryInsert("test.pb.h", "field_set_char:foo.Bar.repeatedString", context);
|
||||
TryInsert("test.pb.h", "field_set_pointer:foo.Bar.repeatedString", context);
|
||||
TryInsert("test.pb.h", "field_mutable:foo.Bar.repeatedString", context);
|
||||
TryInsert("test.pb.h", "field_set_char:foo.Bar.repeatedString", context);
|
||||
TryInsert("test.pb.h", "field_set_pointer:foo.Bar.repeatedString", context);
|
||||
|
||||
// Check field accessors for an int inside oneof{}:
|
||||
TryInsert("test.pb.h", "field_get:foo.Bar.oneOfInt", context);
|
||||
TryInsert("test.pb.h", "field_set:foo.Bar.oneOfInt", context);
|
||||
|
||||
// Check field accessors for a string inside oneof{}:
|
||||
TryInsert("test.pb.h", "field_get:foo.Bar.oneOfString", context);
|
||||
TryInsert("test.pb.h", "field_set:foo.Bar.oneOfString", context);
|
||||
TryInsert("test.pb.h", "field_set_char:foo.Bar.oneOfString", context);
|
||||
TryInsert("test.pb.h", "field_set_pointer:foo.Bar.oneOfString", context);
|
||||
TryInsert("test.pb.h", "field_mutable:foo.Bar.oneOfString", context);
|
||||
TryInsert("test.pb.h", "field_set_allocated:foo.Bar.oneOfString", context);
|
||||
TryInsert("test.pb.h", "field_set_char:foo.Bar.oneOfString", context);
|
||||
TryInsert("test.pb.h", "field_set_pointer:foo.Bar.oneOfString", context);
|
||||
|
||||
// Check field accessors for an optional message:
|
||||
TryInsert("test.pb.h", "field_get:foo.Bar.optMessage", context);
|
||||
TryInsert("test.pb.h", "field_mutable:foo.Bar.optMessage", context);
|
||||
TryInsert("test.pb.h", "field_set_allocated:foo.Bar.optMessage", context);
|
||||
|
||||
// Check field accessors for a repeated message:
|
||||
TryInsert("test.pb.h", "field_add:foo.Bar.repeatedMessage", context);
|
||||
TryInsert("test.pb.h", "field_get:foo.Bar.repeatedMessage", context);
|
||||
TryInsert("test.pb.h", "field_list:foo.Bar.repeatedMessage", context);
|
||||
TryInsert("test.pb.h", "field_mutable:foo.Bar.repeatedMessage", context);
|
||||
TryInsert("test.pb.h", "field_mutable_list:foo.Bar.repeatedMessage",
|
||||
context);
|
||||
|
||||
// Check field accessors for a message inside oneof{}:
|
||||
TryInsert("test.pb.h", "field_get:foo.Bar.oneOfMessage", context);
|
||||
TryInsert("test.pb.h", "field_mutable:foo.Bar.oneOfMessage", context);
|
||||
TryInsert("test.pb.cc", "field_set_allocated:foo.Bar.oneOfMessage",
|
||||
context);
|
||||
|
||||
// Check field accessors for an optional enum:
|
||||
TryInsert("test.pb.h", "field_get:foo.Bar.optEnum", context);
|
||||
TryInsert("test.pb.h", "field_set:foo.Bar.optEnum", context);
|
||||
|
||||
// Check field accessors for a repeated enum:
|
||||
TryInsert("test.pb.h", "field_get:foo.Bar.repeatedEnum", context);
|
||||
TryInsert("test.pb.h", "field_set:foo.Bar.repeatedEnum", context);
|
||||
TryInsert("test.pb.h", "field_add:foo.Bar.repeatedEnum", context);
|
||||
TryInsert("test.pb.h", "field_list:foo.Bar.repeatedEnum", context);
|
||||
TryInsert("test.pb.h", "field_mutable_list:foo.Bar.repeatedEnum", context);
|
||||
|
||||
// Check field accessors for an enum inside oneof{}:
|
||||
TryInsert("test.pb.h", "field_get:foo.Bar.oneOfEnum", context);
|
||||
TryInsert("test.pb.h", "field_set:foo.Bar.oneOfEnum", context);
|
||||
|
||||
// Check field accessors for a required cord:
|
||||
TryInsert("test.pb.h", "field_get:foo.Bar.requiredCord", context);
|
||||
TryInsert("test.pb.h", "field_set:foo.Bar.requiredCord", context);
|
||||
TryInsert("test.pb.h", "field_mutable:foo.Bar.requiredCord", context);
|
||||
|
||||
// Check field accessors for a repeated cord:
|
||||
TryInsert("test.pb.h", "field_get:foo.Bar.repeatedCord", context);
|
||||
TryInsert("test.pb.h", "field_set:foo.Bar.repeatedCord", context);
|
||||
TryInsert("test.pb.h", "field_add:foo.Bar.repeatedCord", context);
|
||||
TryInsert("test.pb.h", "field_list:foo.Bar.repeatedCord", context);
|
||||
TryInsert("test.pb.h", "field_mutable:foo.Bar.repeatedCord", context);
|
||||
TryInsert("test.pb.h", "field_mutable_list:foo.Bar.repeatedCord", context);
|
||||
|
||||
// Check field accessors for a cord inside oneof{}:
|
||||
TryInsert("test.pb.h", "field_get:foo.Bar.oneOfCord", context);
|
||||
TryInsert("test.pb.h", "field_set:foo.Bar.oneOfCord", context);
|
||||
TryInsert("test.pb.h", "field_mutable:foo.Bar.oneOfCord", context);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TryInsert(const std::string& filename,
|
||||
const std::string& insertion_point,
|
||||
GeneratorContext* context) const {
|
||||
std::unique_ptr<io::ZeroCopyOutputStream> output(
|
||||
context->OpenForInsert(filename, insertion_point));
|
||||
io::Printer printer(output.get(), '$');
|
||||
printer.Print("// inserted $name$\n", "name", insertion_point);
|
||||
}
|
||||
};
|
||||
|
||||
// This test verifies that all the expected insertion points exist. It does
|
||||
// not verify that they are correctly-placed; that would require actually
|
||||
// compiling the output which is a bit more than I care to do for this test.
|
||||
TEST(CppPluginTest, PluginTest) {
|
||||
GOOGLE_CHECK_OK(File::SetContents(TestTempDir() + "/test.proto",
|
||||
"syntax = \"proto2\";\n"
|
||||
"package foo;\n"
|
||||
"\n"
|
||||
"enum Thud { VALUE = 0; }\n"
|
||||
"\n"
|
||||
"message Bar {\n"
|
||||
" message Baz {}\n"
|
||||
" optional int32 optInt = 1;\n"
|
||||
" repeated int32 repeatedInt = 2;\n"
|
||||
"\n"
|
||||
" required string requiredString = 3;\n"
|
||||
" repeated string repeatedString = 4;\n"
|
||||
"\n"
|
||||
" optional Baz optMessage = 6;\n"
|
||||
" repeated Baz repeatedMessage = 7;\n"
|
||||
"\n"
|
||||
" optional Thud optEnum = 8;\n"
|
||||
" repeated Thud repeatedEnum = 9;\n"
|
||||
"\n"
|
||||
" required string requiredCord = 10 [\n"
|
||||
" ctype = CORD\n"
|
||||
" ];\n"
|
||||
" repeated string repeatedCord = 11 [\n"
|
||||
" ctype = CORD\n"
|
||||
" ];\n"
|
||||
"\n"
|
||||
" oneof Qux {\n"
|
||||
" int64 oneOfInt = 20;\n"
|
||||
" string oneOfString = 21;\n"
|
||||
" Baz oneOfMessage = 22;\n"
|
||||
" Thud oneOfEnum = 23;"
|
||||
" string oneOfCord = 24 [\n"
|
||||
" ctype = CORD\n"
|
||||
" ];\n"
|
||||
" }\n"
|
||||
"}\n",
|
||||
true));
|
||||
|
||||
CommandLineInterface cli;
|
||||
cli.SetInputsAreProtoPathRelative(true);
|
||||
|
||||
CppGenerator cpp_generator;
|
||||
TestGenerator test_generator;
|
||||
cli.RegisterGenerator("--cpp_out", &cpp_generator, "");
|
||||
cli.RegisterGenerator("--test_out", &test_generator, "");
|
||||
|
||||
std::string proto_path = "-I" + TestTempDir();
|
||||
std::string cpp_out = "--cpp_out=" + TestTempDir();
|
||||
std::string test_out = "--test_out=" + TestTempDir();
|
||||
|
||||
const char* argv[] = {"protoc", proto_path.c_str(), cpp_out.c_str(),
|
||||
test_out.c_str(), "test.proto"};
|
||||
|
||||
EXPECT_EQ(0, cli.Run(5, argv));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
476
ubuntu/google/protobuf/compiler/cpp/cpp_primitive_field.cc
Normal file
476
ubuntu/google/protobuf/compiler/cpp/cpp_primitive_field.cc
Normal file
@@ -0,0 +1,476 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// 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,
|
||||
std::map<std::string, std::string>* variables,
|
||||
const Options& options) {
|
||||
SetCommonFieldVariables(descriptor, variables, options);
|
||||
(*variables)["type"] = PrimitiveTypeName(options, descriptor->cpp_type());
|
||||
(*variables)["default"] = DefaultValue(options, descriptor);
|
||||
(*variables)["tag"] = StrCat(internal::WireFormat::MakeTag(descriptor));
|
||||
int fixed_size = FixedSize(descriptor->type());
|
||||
if (fixed_size != -1) {
|
||||
(*variables)["fixed_size"] = StrCat(fixed_size);
|
||||
}
|
||||
(*variables)["wire_format_field_type"] = FieldDescriptorProto_Type_Name(
|
||||
static_cast<FieldDescriptorProto_Type>(descriptor->type()));
|
||||
(*variables)["full_name"] = descriptor->full_name();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// ===================================================================
|
||||
|
||||
PrimitiveFieldGenerator::PrimitiveFieldGenerator(
|
||||
const FieldDescriptor* descriptor, const Options& options)
|
||||
: FieldGenerator(descriptor, options) {
|
||||
SetPrimitiveVariables(descriptor, &variables_, options);
|
||||
}
|
||||
|
||||
PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {}
|
||||
|
||||
void PrimitiveFieldGenerator::GeneratePrivateMembers(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("$type$ $name$_;\n");
|
||||
}
|
||||
|
||||
void PrimitiveFieldGenerator::GenerateAccessorDeclarations(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format(
|
||||
"$deprecated_attr$$type$ ${1$$name$$}$() const;\n"
|
||||
"$deprecated_attr$void ${1$set_$name$$}$($type$ value);\n"
|
||||
"private:\n"
|
||||
"$type$ ${1$_internal_$name$$}$() const;\n"
|
||||
"void ${1$_internal_set_$name$$}$($type$ value);\n"
|
||||
"public:\n",
|
||||
descriptor_);
|
||||
}
|
||||
|
||||
void PrimitiveFieldGenerator::GenerateInlineAccessorDefinitions(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format(
|
||||
"inline $type$ $classname$::_internal_$name$() const {\n"
|
||||
" return $name$_;\n"
|
||||
"}\n"
|
||||
"inline $type$ $classname$::$name$() const {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_get:$full_name$)\n"
|
||||
" return _internal_$name$();\n"
|
||||
"}\n"
|
||||
"inline void $classname$::_internal_set_$name$($type$ value) {\n"
|
||||
" $set_hasbit$\n"
|
||||
" $name$_ = value;\n"
|
||||
"}\n"
|
||||
"inline void $classname$::set_$name$($type$ value) {\n"
|
||||
"$annotate_accessor$"
|
||||
" _internal_set_$name$(value);\n"
|
||||
" // @@protoc_insertion_point(field_set:$full_name$)\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
void PrimitiveFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("$name$_ = $default$;\n");
|
||||
}
|
||||
|
||||
void PrimitiveFieldGenerator::GenerateMergingCode(io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("_internal_set_$name$(from._internal_$name$());\n");
|
||||
}
|
||||
|
||||
void PrimitiveFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("swap($name$_, other->$name$_);\n");
|
||||
}
|
||||
|
||||
void PrimitiveFieldGenerator::GenerateConstructorCode(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("$name$_ = $default$;\n");
|
||||
}
|
||||
|
||||
void PrimitiveFieldGenerator::GenerateCopyConstructorCode(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("$name$_ = from.$name$_;\n");
|
||||
}
|
||||
|
||||
void PrimitiveFieldGenerator::GenerateSerializeWithCachedSizesToArray(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format(
|
||||
"target = stream->EnsureSpace(target);\n"
|
||||
"target = "
|
||||
"::$proto_ns$::internal::WireFormatLite::Write$declared_type$ToArray("
|
||||
"$number$, this->_internal_$name$(), target);\n");
|
||||
}
|
||||
|
||||
void PrimitiveFieldGenerator::GenerateByteSize(io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
int fixed_size = FixedSize(descriptor_->type());
|
||||
if (fixed_size == -1) {
|
||||
format(
|
||||
"total_size += $tag_size$ +\n"
|
||||
" ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n"
|
||||
" this->_internal_$name$());\n");
|
||||
} else {
|
||||
format("total_size += $tag_size$ + $fixed_size$;\n");
|
||||
}
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
|
||||
PrimitiveOneofFieldGenerator::PrimitiveOneofFieldGenerator(
|
||||
const FieldDescriptor* descriptor, const Options& options)
|
||||
: PrimitiveFieldGenerator(descriptor, options) {
|
||||
SetCommonOneofFieldVariables(descriptor, &variables_);
|
||||
}
|
||||
|
||||
PrimitiveOneofFieldGenerator::~PrimitiveOneofFieldGenerator() {}
|
||||
|
||||
void PrimitiveOneofFieldGenerator::GenerateInlineAccessorDefinitions(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format(
|
||||
"inline $type$ $classname$::_internal_$name$() const {\n"
|
||||
" if (_internal_has_$name$()) {\n"
|
||||
" return $field_member$;\n"
|
||||
" }\n"
|
||||
" return $default$;\n"
|
||||
"}\n"
|
||||
"inline void $classname$::_internal_set_$name$($type$ value) {\n"
|
||||
" if (!_internal_has_$name$()) {\n"
|
||||
" clear_$oneof_name$();\n"
|
||||
" set_has_$name$();\n"
|
||||
" }\n"
|
||||
" $field_member$ = value;\n"
|
||||
"}\n"
|
||||
"inline $type$ $classname$::$name$() const {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_get:$full_name$)\n"
|
||||
" return _internal_$name$();\n"
|
||||
"}\n"
|
||||
"inline void $classname$::set_$name$($type$ value) {\n"
|
||||
"$annotate_accessor$"
|
||||
" _internal_set_$name$(value);\n"
|
||||
" // @@protoc_insertion_point(field_set:$full_name$)\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
void PrimitiveOneofFieldGenerator::GenerateClearingCode(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("$field_member$ = $default$;\n");
|
||||
}
|
||||
|
||||
void PrimitiveOneofFieldGenerator::GenerateSwappingCode(
|
||||
io::Printer* printer) const {
|
||||
// Don't print any swapping code. Swapping the union will swap this field.
|
||||
}
|
||||
|
||||
void PrimitiveOneofFieldGenerator::GenerateConstructorCode(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("$ns$::_$classname$_default_instance_.$name$_ = $default$;\n");
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
|
||||
RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator(
|
||||
const FieldDescriptor* descriptor, const Options& options)
|
||||
: FieldGenerator(descriptor, options) {
|
||||
SetPrimitiveVariables(descriptor, &variables_, options);
|
||||
|
||||
if (descriptor->is_packed()) {
|
||||
variables_["packed_reader"] = "ReadPackedPrimitive";
|
||||
variables_["repeated_reader"] = "ReadRepeatedPrimitiveNoInline";
|
||||
} else {
|
||||
variables_["packed_reader"] = "ReadPackedPrimitiveNoInline";
|
||||
variables_["repeated_reader"] = "ReadRepeatedPrimitive";
|
||||
}
|
||||
}
|
||||
|
||||
RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {}
|
||||
|
||||
void RepeatedPrimitiveFieldGenerator::GeneratePrivateMembers(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("::$proto_ns$::RepeatedField< $type$ > $name$_;\n");
|
||||
if (descriptor_->is_packed() &&
|
||||
HasGeneratedMethods(descriptor_->file(), options_)) {
|
||||
format("mutable std::atomic<int> _$name$_cached_byte_size_;\n");
|
||||
}
|
||||
}
|
||||
|
||||
void RepeatedPrimitiveFieldGenerator::GenerateAccessorDeclarations(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format(
|
||||
"private:\n"
|
||||
"$type$ ${1$_internal_$name$$}$(int index) const;\n"
|
||||
"const ::$proto_ns$::RepeatedField< $type$ >&\n"
|
||||
" ${1$_internal_$name$$}$() const;\n"
|
||||
"void ${1$_internal_add_$name$$}$($type$ value);\n"
|
||||
"::$proto_ns$::RepeatedField< $type$ >*\n"
|
||||
" ${1$_internal_mutable_$name$$}$();\n"
|
||||
"public:\n"
|
||||
"$deprecated_attr$$type$ ${1$$name$$}$(int index) const;\n"
|
||||
"$deprecated_attr$void ${1$set_$name$$}$(int index, $type$ value);\n"
|
||||
"$deprecated_attr$void ${1$add_$name$$}$($type$ value);\n"
|
||||
"$deprecated_attr$const ::$proto_ns$::RepeatedField< $type$ >&\n"
|
||||
" ${1$$name$$}$() const;\n"
|
||||
"$deprecated_attr$::$proto_ns$::RepeatedField< $type$ >*\n"
|
||||
" ${1$mutable_$name$$}$();\n",
|
||||
descriptor_);
|
||||
}
|
||||
|
||||
void RepeatedPrimitiveFieldGenerator::GenerateInlineAccessorDefinitions(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format(
|
||||
"inline $type$ $classname$::_internal_$name$(int index) const {\n"
|
||||
" return $name$_.Get(index);\n"
|
||||
"}\n"
|
||||
"inline $type$ $classname$::$name$(int index) const {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_get:$full_name$)\n"
|
||||
" return _internal_$name$(index);\n"
|
||||
"}\n"
|
||||
"inline void $classname$::set_$name$(int index, $type$ value) {\n"
|
||||
"$annotate_accessor$"
|
||||
" $name$_.Set(index, value);\n"
|
||||
" // @@protoc_insertion_point(field_set:$full_name$)\n"
|
||||
"}\n"
|
||||
"inline void $classname$::_internal_add_$name$($type$ value) {\n"
|
||||
" $name$_.Add(value);\n"
|
||||
"}\n"
|
||||
"inline void $classname$::add_$name$($type$ value) {\n"
|
||||
"$annotate_accessor$"
|
||||
" _internal_add_$name$(value);\n"
|
||||
" // @@protoc_insertion_point(field_add:$full_name$)\n"
|
||||
"}\n"
|
||||
"inline const ::$proto_ns$::RepeatedField< $type$ >&\n"
|
||||
"$classname$::_internal_$name$() const {\n"
|
||||
" return $name$_;\n"
|
||||
"}\n"
|
||||
"inline const ::$proto_ns$::RepeatedField< $type$ >&\n"
|
||||
"$classname$::$name$() const {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_list:$full_name$)\n"
|
||||
" return _internal_$name$();\n"
|
||||
"}\n"
|
||||
"inline ::$proto_ns$::RepeatedField< $type$ >*\n"
|
||||
"$classname$::_internal_mutable_$name$() {\n"
|
||||
" return &$name$_;\n"
|
||||
"}\n"
|
||||
"inline ::$proto_ns$::RepeatedField< $type$ >*\n"
|
||||
"$classname$::mutable_$name$() {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
|
||||
" return _internal_mutable_$name$();\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
void RepeatedPrimitiveFieldGenerator::GenerateClearingCode(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("$name$_.Clear();\n");
|
||||
}
|
||||
|
||||
void RepeatedPrimitiveFieldGenerator::GenerateMergingCode(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("$name$_.MergeFrom(from.$name$_);\n");
|
||||
}
|
||||
|
||||
void RepeatedPrimitiveFieldGenerator::GenerateSwappingCode(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("$name$_.InternalSwap(&other->$name$_);\n");
|
||||
}
|
||||
|
||||
void RepeatedPrimitiveFieldGenerator::GenerateConstructorCode(
|
||||
io::Printer* printer) const {
|
||||
// Not needed for repeated fields.
|
||||
}
|
||||
|
||||
void RepeatedPrimitiveFieldGenerator::GenerateCopyConstructorCode(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("$name$_.CopyFrom(from.$name$_);\n");
|
||||
}
|
||||
|
||||
void RepeatedPrimitiveFieldGenerator::GenerateSerializeWithCachedSizesToArray(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
if (descriptor_->is_packed()) {
|
||||
if (FixedSize(descriptor_->type()) > 0) {
|
||||
format(
|
||||
"if (this->_internal_$name$_size() > 0) {\n"
|
||||
" target = stream->WriteFixedPacked($number$, _internal_$name$(), "
|
||||
"target);\n"
|
||||
"}\n");
|
||||
} else {
|
||||
format(
|
||||
"{\n"
|
||||
" int byte_size = "
|
||||
"_$name$_cached_byte_size_.load(std::memory_order_relaxed);\n"
|
||||
" if (byte_size > 0) {\n"
|
||||
" target = stream->Write$declared_type$Packed(\n"
|
||||
" $number$, _internal_$name$(), byte_size, target);\n"
|
||||
" }\n"
|
||||
"}\n");
|
||||
}
|
||||
} else {
|
||||
format(
|
||||
"for (int i = 0, n = this->_internal_$name$_size(); i < n; i++) {\n"
|
||||
" target = stream->EnsureSpace(target);\n"
|
||||
" target = ::$proto_ns$::internal::WireFormatLite::"
|
||||
"Write$declared_type$ToArray($number$, this->_internal_$name$(i), "
|
||||
"target);\n"
|
||||
"}\n");
|
||||
}
|
||||
}
|
||||
|
||||
void RepeatedPrimitiveFieldGenerator::GenerateByteSize(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("{\n");
|
||||
format.Indent();
|
||||
int fixed_size = FixedSize(descriptor_->type());
|
||||
if (fixed_size == -1) {
|
||||
format(
|
||||
"size_t data_size = ::$proto_ns$::internal::WireFormatLite::\n"
|
||||
" $declared_type$Size(this->$name$_);\n");
|
||||
} else {
|
||||
format(
|
||||
"unsigned int count = static_cast<unsigned "
|
||||
"int>(this->_internal_$name$_size());\n"
|
||||
"size_t data_size = $fixed_size$UL * count;\n");
|
||||
}
|
||||
|
||||
if (descriptor_->is_packed()) {
|
||||
format(
|
||||
"if (data_size > 0) {\n"
|
||||
" total_size += $tag_size$ +\n"
|
||||
" ::$proto_ns$::internal::WireFormatLite::Int32Size(\n"
|
||||
" static_cast<$int32$>(data_size));\n"
|
||||
"}\n"
|
||||
"int cached_size = ::$proto_ns$::internal::ToCachedSize(data_size);\n"
|
||||
"_$name$_cached_byte_size_.store(cached_size,\n"
|
||||
" std::memory_order_relaxed);\n"
|
||||
"total_size += data_size;\n");
|
||||
} else {
|
||||
format(
|
||||
"total_size += $tag_size$ *\n"
|
||||
" "
|
||||
"::$proto_ns$::internal::FromIntSize(this->_internal_$name$_size());\n"
|
||||
"total_size += data_size;\n");
|
||||
}
|
||||
format.Outdent();
|
||||
format("}\n");
|
||||
}
|
||||
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
112
ubuntu/google/protobuf/compiler/cpp/cpp_primitive_field.h
Normal file
112
ubuntu/google/protobuf/compiler/cpp/cpp_primitive_field.h
Normal file
@@ -0,0 +1,112 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Author: kenton@google.com (Kenton Varda)
|
||||
// Based on original Protocol Buffers design by
|
||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_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:
|
||||
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 GenerateCopyConstructorCode(io::Printer* printer) const;
|
||||
void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
|
||||
void GenerateByteSize(io::Printer* printer) const;
|
||||
|
||||
private:
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator);
|
||||
};
|
||||
|
||||
class PrimitiveOneofFieldGenerator : public PrimitiveFieldGenerator {
|
||||
public:
|
||||
PrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor,
|
||||
const Options& options);
|
||||
~PrimitiveOneofFieldGenerator();
|
||||
|
||||
// implements FieldGenerator ---------------------------------------
|
||||
void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
|
||||
void GenerateClearingCode(io::Printer* printer) const;
|
||||
void GenerateSwappingCode(io::Printer* printer) const;
|
||||
void GenerateConstructorCode(io::Printer* printer) const;
|
||||
|
||||
private:
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveOneofFieldGenerator);
|
||||
};
|
||||
|
||||
class RepeatedPrimitiveFieldGenerator : public FieldGenerator {
|
||||
public:
|
||||
RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
|
||||
const Options& options);
|
||||
~RepeatedPrimitiveFieldGenerator();
|
||||
|
||||
// implements FieldGenerator ---------------------------------------
|
||||
void GeneratePrivateMembers(io::Printer* printer) const;
|
||||
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 GenerateCopyConstructorCode(io::Printer* printer) const;
|
||||
void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
|
||||
void GenerateByteSize(io::Printer* printer) const;
|
||||
|
||||
private:
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPrimitiveFieldGenerator);
|
||||
};
|
||||
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_CPP_PRIMITIVE_FIELD_H__
|
||||
327
ubuntu/google/protobuf/compiler/cpp/cpp_service.cc
Normal file
327
ubuntu/google/protobuf/compiler/cpp/cpp_service.cc
Normal file
@@ -0,0 +1,327 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Author: kenton@google.com (Kenton Varda)
|
||||
// Based on original Protocol Buffers design by
|
||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||
|
||||
#include <google/protobuf/compiler/cpp/cpp_service.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 InitMethodVariables(const MethodDescriptor* method, const Options& options,
|
||||
Formatter* format) {
|
||||
format->Set("name", method->name());
|
||||
format->Set("input_type", QualifiedClassName(method->input_type(), options));
|
||||
format->Set("output_type",
|
||||
QualifiedClassName(method->output_type(), options));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ServiceGenerator::ServiceGenerator(
|
||||
const ServiceDescriptor* descriptor,
|
||||
const std::map<std::string, std::string>& vars, const Options& options)
|
||||
: descriptor_(descriptor), vars_(vars), options_(options) {
|
||||
vars_["classname"] = descriptor_->name();
|
||||
vars_["full_name"] = descriptor_->full_name();
|
||||
}
|
||||
|
||||
ServiceGenerator::~ServiceGenerator() {}
|
||||
|
||||
void ServiceGenerator::GenerateDeclarations(io::Printer* printer) {
|
||||
Formatter format(printer, vars_);
|
||||
// Forward-declare the stub type.
|
||||
format(
|
||||
"class $classname$_Stub;\n"
|
||||
"\n");
|
||||
|
||||
GenerateInterface(printer);
|
||||
GenerateStubDefinition(printer);
|
||||
}
|
||||
|
||||
void ServiceGenerator::GenerateInterface(io::Printer* printer) {
|
||||
Formatter format(printer, vars_);
|
||||
format(
|
||||
"class $dllexport_decl $$classname$ : public ::$proto_ns$::Service {\n"
|
||||
" protected:\n"
|
||||
" // This class should be treated as an abstract interface.\n"
|
||||
" inline $classname$() {};\n"
|
||||
" public:\n"
|
||||
" virtual ~$classname$();\n");
|
||||
printer->Indent();
|
||||
|
||||
format(
|
||||
"\n"
|
||||
"typedef $classname$_Stub Stub;\n"
|
||||
"\n"
|
||||
"static const ::$proto_ns$::ServiceDescriptor* descriptor();\n"
|
||||
"\n");
|
||||
|
||||
GenerateMethodSignatures(VIRTUAL, printer);
|
||||
|
||||
format(
|
||||
"\n"
|
||||
"// implements Service ----------------------------------------------\n"
|
||||
"\n"
|
||||
"const ::$proto_ns$::ServiceDescriptor* GetDescriptor();\n"
|
||||
"void CallMethod(const ::$proto_ns$::MethodDescriptor* method,\n"
|
||||
" ::$proto_ns$::RpcController* controller,\n"
|
||||
" const ::$proto_ns$::Message* request,\n"
|
||||
" ::$proto_ns$::Message* response,\n"
|
||||
" ::google::protobuf::Closure* done);\n"
|
||||
"const ::$proto_ns$::Message& GetRequestPrototype(\n"
|
||||
" const ::$proto_ns$::MethodDescriptor* method) const;\n"
|
||||
"const ::$proto_ns$::Message& GetResponsePrototype(\n"
|
||||
" const ::$proto_ns$::MethodDescriptor* method) const;\n");
|
||||
|
||||
printer->Outdent();
|
||||
format(
|
||||
"\n"
|
||||
" private:\n"
|
||||
" GOOGLE_DISALLOW_EVIL_CONSTRUCTORS($classname$);\n"
|
||||
"};\n"
|
||||
"\n");
|
||||
}
|
||||
|
||||
void ServiceGenerator::GenerateStubDefinition(io::Printer* printer) {
|
||||
Formatter format(printer, vars_);
|
||||
format(
|
||||
"class $dllexport_decl $$classname$_Stub : public $classname$ {\n"
|
||||
" public:\n");
|
||||
|
||||
printer->Indent();
|
||||
|
||||
format(
|
||||
"$classname$_Stub(::$proto_ns$::RpcChannel* channel);\n"
|
||||
"$classname$_Stub(::$proto_ns$::RpcChannel* channel,\n"
|
||||
" ::$proto_ns$::Service::ChannelOwnership ownership);\n"
|
||||
"~$classname$_Stub();\n"
|
||||
"\n"
|
||||
"inline ::$proto_ns$::RpcChannel* channel() { return channel_; }\n"
|
||||
"\n"
|
||||
"// implements $classname$ ------------------------------------------\n"
|
||||
"\n");
|
||||
|
||||
GenerateMethodSignatures(NON_VIRTUAL, printer);
|
||||
|
||||
printer->Outdent();
|
||||
format(
|
||||
" private:\n"
|
||||
" ::$proto_ns$::RpcChannel* channel_;\n"
|
||||
" bool owns_channel_;\n"
|
||||
" GOOGLE_DISALLOW_EVIL_CONSTRUCTORS($classname$_Stub);\n"
|
||||
"};\n"
|
||||
"\n");
|
||||
}
|
||||
|
||||
void ServiceGenerator::GenerateMethodSignatures(VirtualOrNon virtual_or_non,
|
||||
io::Printer* printer) {
|
||||
for (int i = 0; i < descriptor_->method_count(); i++) {
|
||||
const MethodDescriptor* method = descriptor_->method(i);
|
||||
Formatter format(printer, vars_);
|
||||
InitMethodVariables(method, options_, &format);
|
||||
format.Set("virtual", virtual_or_non == VIRTUAL ? "virtual " : "");
|
||||
format(
|
||||
"$virtual$void $name$(::$proto_ns$::RpcController* controller,\n"
|
||||
" const $input_type$* request,\n"
|
||||
" $output_type$* response,\n"
|
||||
" ::google::protobuf::Closure* done);\n");
|
||||
}
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
|
||||
void ServiceGenerator::GenerateImplementation(io::Printer* printer) {
|
||||
Formatter format(printer, vars_);
|
||||
format(
|
||||
"$classname$::~$classname$() {}\n"
|
||||
"\n"
|
||||
"const ::$proto_ns$::ServiceDescriptor* $classname$::descriptor() {\n"
|
||||
" "
|
||||
"::$proto_ns$::internal::AssignDescriptors(&$desc_table$);\n"
|
||||
" return $file_level_service_descriptors$[$1$];\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"const ::$proto_ns$::ServiceDescriptor* $classname$::GetDescriptor() {\n"
|
||||
" return descriptor();\n"
|
||||
"}\n"
|
||||
"\n",
|
||||
index_in_metadata_);
|
||||
|
||||
// Generate methods of the interface.
|
||||
GenerateNotImplementedMethods(printer);
|
||||
GenerateCallMethod(printer);
|
||||
GenerateGetPrototype(REQUEST, printer);
|
||||
GenerateGetPrototype(RESPONSE, printer);
|
||||
|
||||
// Generate stub implementation.
|
||||
format(
|
||||
"$classname$_Stub::$classname$_Stub(::$proto_ns$::RpcChannel* channel)\n"
|
||||
" : channel_(channel), owns_channel_(false) {}\n"
|
||||
"$classname$_Stub::$classname$_Stub(\n"
|
||||
" ::$proto_ns$::RpcChannel* channel,\n"
|
||||
" ::$proto_ns$::Service::ChannelOwnership ownership)\n"
|
||||
" : channel_(channel),\n"
|
||||
" owns_channel_(ownership == "
|
||||
"::$proto_ns$::Service::STUB_OWNS_CHANNEL) "
|
||||
"{}\n"
|
||||
"$classname$_Stub::~$classname$_Stub() {\n"
|
||||
" if (owns_channel_) delete channel_;\n"
|
||||
"}\n"
|
||||
"\n");
|
||||
|
||||
GenerateStubMethods(printer);
|
||||
}
|
||||
|
||||
void ServiceGenerator::GenerateNotImplementedMethods(io::Printer* printer) {
|
||||
for (int i = 0; i < descriptor_->method_count(); i++) {
|
||||
const MethodDescriptor* method = descriptor_->method(i);
|
||||
Formatter format(printer, vars_);
|
||||
InitMethodVariables(method, options_, &format);
|
||||
format(
|
||||
"void $classname$::$name$(::$proto_ns$::RpcController* controller,\n"
|
||||
" const $input_type$*,\n"
|
||||
" $output_type$*,\n"
|
||||
" ::google::protobuf::Closure* done) {\n"
|
||||
" controller->SetFailed(\"Method $name$() not implemented.\");\n"
|
||||
" done->Run();\n"
|
||||
"}\n"
|
||||
"\n");
|
||||
}
|
||||
}
|
||||
|
||||
void ServiceGenerator::GenerateCallMethod(io::Printer* printer) {
|
||||
Formatter format(printer, vars_);
|
||||
format(
|
||||
"void $classname$::CallMethod(const ::$proto_ns$::MethodDescriptor* "
|
||||
"method,\n"
|
||||
" ::$proto_ns$::RpcController* controller,\n"
|
||||
" const ::$proto_ns$::Message* request,\n"
|
||||
" ::$proto_ns$::Message* response,\n"
|
||||
" ::google::protobuf::Closure* done) {\n"
|
||||
" GOOGLE_DCHECK_EQ(method->service(), $file_level_service_descriptors$[$1$]);\n"
|
||||
" switch(method->index()) {\n",
|
||||
index_in_metadata_);
|
||||
|
||||
for (int i = 0; i < descriptor_->method_count(); i++) {
|
||||
const MethodDescriptor* method = descriptor_->method(i);
|
||||
Formatter format(printer, vars_);
|
||||
InitMethodVariables(method, options_, &format);
|
||||
|
||||
// Note: down_cast does not work here because it only works on pointers,
|
||||
// not references.
|
||||
format(
|
||||
" case $1$:\n"
|
||||
" $name$(controller,\n"
|
||||
" ::$proto_ns$::internal::DownCast<const $input_type$*>(\n"
|
||||
" request),\n"
|
||||
" ::$proto_ns$::internal::DownCast<$output_type$*>(\n"
|
||||
" response),\n"
|
||||
" done);\n"
|
||||
" break;\n",
|
||||
i);
|
||||
}
|
||||
|
||||
format(
|
||||
" default:\n"
|
||||
" GOOGLE_LOG(FATAL) << \"Bad method index; this should never happen.\";\n"
|
||||
" break;\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"\n");
|
||||
}
|
||||
|
||||
void ServiceGenerator::GenerateGetPrototype(RequestOrResponse which,
|
||||
io::Printer* printer) {
|
||||
Formatter format(printer, vars_);
|
||||
if (which == REQUEST) {
|
||||
format("const ::$proto_ns$::Message& $classname$::GetRequestPrototype(\n");
|
||||
} else {
|
||||
format("const ::$proto_ns$::Message& $classname$::GetResponsePrototype(\n");
|
||||
}
|
||||
|
||||
format(
|
||||
" const ::$proto_ns$::MethodDescriptor* method) const {\n"
|
||||
" GOOGLE_DCHECK_EQ(method->service(), descriptor());\n"
|
||||
" switch(method->index()) {\n");
|
||||
|
||||
for (int i = 0; i < descriptor_->method_count(); i++) {
|
||||
const MethodDescriptor* method = descriptor_->method(i);
|
||||
const Descriptor* type =
|
||||
(which == REQUEST) ? method->input_type() : method->output_type();
|
||||
|
||||
format(
|
||||
" case $1$:\n"
|
||||
" return $2$::default_instance();\n",
|
||||
i, QualifiedClassName(type, options_));
|
||||
}
|
||||
|
||||
format(
|
||||
" default:\n"
|
||||
" GOOGLE_LOG(FATAL) << \"Bad method index; this should never happen.\";\n"
|
||||
" return *::$proto_ns$::MessageFactory::generated_factory()\n"
|
||||
" ->GetPrototype(method->$1$_type());\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"\n",
|
||||
which == REQUEST ? "input" : "output");
|
||||
}
|
||||
|
||||
void ServiceGenerator::GenerateStubMethods(io::Printer* printer) {
|
||||
for (int i = 0; i < descriptor_->method_count(); i++) {
|
||||
const MethodDescriptor* method = descriptor_->method(i);
|
||||
Formatter format(printer, vars_);
|
||||
InitMethodVariables(method, options_, &format);
|
||||
format(
|
||||
"void $classname$_Stub::$name$(::$proto_ns$::RpcController* "
|
||||
"controller,\n"
|
||||
" const $input_type$* request,\n"
|
||||
" $output_type$* response,\n"
|
||||
" ::google::protobuf::Closure* done) {\n"
|
||||
" channel_->CallMethod(descriptor()->method($1$),\n"
|
||||
" controller, request, response, done);\n"
|
||||
"}\n",
|
||||
i);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
122
ubuntu/google/protobuf/compiler/cpp/cpp_service.h
Normal file
122
ubuntu/google/protobuf/compiler/cpp/cpp_service.h
Normal file
@@ -0,0 +1,122 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Author: kenton@google.com (Kenton Varda)
|
||||
// Based on original Protocol Buffers design by
|
||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_SERVICE_H__
|
||||
#define GOOGLE_PROTOBUF_COMPILER_CPP_SERVICE_H__
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <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 google
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace cpp {
|
||||
|
||||
class ServiceGenerator {
|
||||
public:
|
||||
// See generator.cc for the meaning of dllexport_decl.
|
||||
explicit ServiceGenerator(const ServiceDescriptor* descriptor,
|
||||
const std::map<std::string, std::string>& vars,
|
||||
const Options& options);
|
||||
~ServiceGenerator();
|
||||
|
||||
// Header stuff.
|
||||
|
||||
// Generate the class definitions for the service's interface and the
|
||||
// stub implementation.
|
||||
void GenerateDeclarations(io::Printer* printer);
|
||||
|
||||
// Source file stuff.
|
||||
|
||||
// Generate implementations of everything declared by
|
||||
// GenerateDeclarations().
|
||||
void GenerateImplementation(io::Printer* printer);
|
||||
|
||||
private:
|
||||
enum RequestOrResponse { REQUEST, RESPONSE };
|
||||
enum VirtualOrNon { VIRTUAL, NON_VIRTUAL };
|
||||
|
||||
// Header stuff.
|
||||
|
||||
// Generate the service abstract interface.
|
||||
void GenerateInterface(io::Printer* printer);
|
||||
|
||||
// Generate the stub class definition.
|
||||
void GenerateStubDefinition(io::Printer* printer);
|
||||
|
||||
// Prints signatures for all methods in the
|
||||
void GenerateMethodSignatures(VirtualOrNon virtual_or_non,
|
||||
io::Printer* printer);
|
||||
|
||||
// Source file stuff.
|
||||
|
||||
// Generate the default implementations of the service methods, which
|
||||
// produce a "not implemented" error.
|
||||
void GenerateNotImplementedMethods(io::Printer* printer);
|
||||
|
||||
// Generate the CallMethod() method of the service.
|
||||
void GenerateCallMethod(io::Printer* printer);
|
||||
|
||||
// Generate the Get{Request,Response}Prototype() methods.
|
||||
void GenerateGetPrototype(RequestOrResponse which, io::Printer* printer);
|
||||
|
||||
// Generate the stub's implementations of the service methods.
|
||||
void GenerateStubMethods(io::Printer* printer);
|
||||
|
||||
const ServiceDescriptor* descriptor_;
|
||||
std::map<std::string, std::string> vars_;
|
||||
const Options& options_;
|
||||
|
||||
int index_in_metadata_;
|
||||
|
||||
friend class FileGenerator;
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ServiceGenerator);
|
||||
};
|
||||
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_CPP_SERVICE_H__
|
||||
824
ubuntu/google/protobuf/compiler/cpp/cpp_string_field.cc
Normal file
824
ubuntu/google/protobuf/compiler/cpp/cpp_string_field.cc
Normal file
@@ -0,0 +1,824 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// 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/descriptor.pb.h>
|
||||
#include <google/protobuf/io/printer.h>
|
||||
#include <google/protobuf/stubs/strutil.h>
|
||||
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace cpp {
|
||||
|
||||
namespace {
|
||||
|
||||
void SetStringVariables(const FieldDescriptor* descriptor,
|
||||
std::map<std::string, std::string>* variables,
|
||||
const Options& options) {
|
||||
SetCommonFieldVariables(descriptor, variables, options);
|
||||
(*variables)["default"] = DefaultValue(options, descriptor);
|
||||
(*variables)["default_length"] =
|
||||
StrCat(descriptor->default_value_string().length());
|
||||
std::string default_variable_string = MakeDefaultName(descriptor);
|
||||
(*variables)["default_variable_name"] = default_variable_string;
|
||||
|
||||
if (!descriptor->default_value_string().empty()) {
|
||||
(*variables)["lazy_variable"] =
|
||||
QualifiedClassName(descriptor->containing_type(), options) +
|
||||
"::" + default_variable_string;
|
||||
}
|
||||
|
||||
(*variables)["default_string"] =
|
||||
descriptor->default_value_string().empty()
|
||||
? "::" + (*variables)["proto_ns"] +
|
||||
"::internal::GetEmptyStringAlreadyInited()"
|
||||
: (*variables)["lazy_variable"] + ".get()";
|
||||
(*variables)["init_value"] =
|
||||
descriptor->default_value_string().empty()
|
||||
? "&::" + (*variables)["proto_ns"] +
|
||||
"::internal::GetEmptyStringAlreadyInited()"
|
||||
: "nullptr";
|
||||
(*variables)["default_value_tag"] =
|
||||
"::" + (*variables)["proto_ns"] + "::internal::ArenaStringPtr::" +
|
||||
(descriptor->default_value_string().empty() ? "Empty" : "NonEmpty") +
|
||||
"Default{}";
|
||||
(*variables)["default_variable_or_tag"] =
|
||||
(*variables)[descriptor->default_value_string().empty()
|
||||
? "default_value_tag"
|
||||
: "lazy_variable"];
|
||||
(*variables)["pointer_type"] =
|
||||
descriptor->type() == FieldDescriptor::TYPE_BYTES ? "void" : "char";
|
||||
(*variables)["null_check"] = (*variables)["DCHK"] + "(value != nullptr);\n";
|
||||
// NOTE: Escaped here to unblock proto1->proto2 migration.
|
||||
// TODO(liujisi): Extend this to apply for other conflicting methods.
|
||||
(*variables)["release_name"] =
|
||||
SafeFunctionName(descriptor->containing_type(), descriptor, "release_");
|
||||
(*variables)["full_name"] = descriptor->full_name();
|
||||
|
||||
if (options.opensource_runtime) {
|
||||
(*variables)["string_piece"] = "::std::string";
|
||||
} else {
|
||||
(*variables)["string_piece"] = "::StringPiece";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// ===================================================================
|
||||
|
||||
StringFieldGenerator::StringFieldGenerator(const FieldDescriptor* descriptor,
|
||||
const Options& options)
|
||||
: FieldGenerator(descriptor, options) {
|
||||
SetStringVariables(descriptor, &variables_, options);
|
||||
}
|
||||
|
||||
StringFieldGenerator::~StringFieldGenerator() {}
|
||||
|
||||
void StringFieldGenerator::GeneratePrivateMembers(io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("::$proto_ns$::internal::ArenaStringPtr $name$_;\n");
|
||||
}
|
||||
|
||||
void StringFieldGenerator::GenerateStaticMembers(io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
if (!descriptor_->default_value_string().empty()) {
|
||||
format(
|
||||
"static const ::$proto_ns$::internal::LazyString"
|
||||
" $default_variable_name$;\n");
|
||||
}
|
||||
}
|
||||
|
||||
void StringFieldGenerator::GenerateAccessorDeclarations(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
// If we're using StringFieldGenerator for a field with a ctype, it's
|
||||
// because that ctype isn't actually implemented. In particular, this is
|
||||
// true of ctype=CORD and ctype=STRING_PIECE in the open source release.
|
||||
// We aren't releasing Cord because it has too many Google-specific
|
||||
// dependencies and we aren't releasing StringPiece because it's hardly
|
||||
// useful outside of Google and because it would get confusing to have
|
||||
// multiple instances of the StringPiece class in different libraries (PCRE
|
||||
// already includes it for their C++ bindings, which came from Google).
|
||||
//
|
||||
// In any case, we make all the accessors private while still actually
|
||||
// using a string to represent the field internally. This way, we can
|
||||
// guarantee that if we do ever implement the ctype, it won't break any
|
||||
// existing users who might be -- for whatever reason -- already using .proto
|
||||
// files that applied the ctype. The field can still be accessed via the
|
||||
// reflection interface since the reflection interface is independent of
|
||||
// the string's underlying representation.
|
||||
|
||||
bool unknown_ctype = descriptor_->options().ctype() !=
|
||||
EffectiveStringCType(descriptor_, options_);
|
||||
|
||||
if (unknown_ctype) {
|
||||
format.Outdent();
|
||||
format(
|
||||
" private:\n"
|
||||
" // Hidden due to unknown ctype option.\n");
|
||||
format.Indent();
|
||||
}
|
||||
|
||||
format(
|
||||
"$deprecated_attr$const std::string& ${1$$name$$}$() const;\n"
|
||||
"$deprecated_attr$void ${1$set_$name$$}$(const std::string& value);\n"
|
||||
"$deprecated_attr$void ${1$set_$name$$}$(std::string&& value);\n"
|
||||
"$deprecated_attr$void ${1$set_$name$$}$(const char* value);\n",
|
||||
descriptor_);
|
||||
if (!options_.opensource_runtime) {
|
||||
format(
|
||||
"$deprecated_attr$void ${1$set_$name$$}$(::StringPiece value);\n",
|
||||
descriptor_);
|
||||
}
|
||||
format(
|
||||
"$deprecated_attr$void ${1$set_$name$$}$(const $pointer_type$* "
|
||||
"value, size_t size)"
|
||||
";\n"
|
||||
"$deprecated_attr$std::string* ${1$mutable_$name$$}$();\n"
|
||||
"$deprecated_attr$std::string* ${1$$release_name$$}$();\n"
|
||||
"$deprecated_attr$void ${1$set_allocated_$name$$}$(std::string* "
|
||||
"$name$);\n",
|
||||
descriptor_);
|
||||
format(
|
||||
"private:\n"
|
||||
"const std::string& _internal_$name$() const;\n"
|
||||
"void _internal_set_$name$(const std::string& value);\n"
|
||||
"std::string* _internal_mutable_$name$();\n"
|
||||
"public:\n");
|
||||
|
||||
if (unknown_ctype) {
|
||||
format.Outdent();
|
||||
format(" public:\n");
|
||||
format.Indent();
|
||||
}
|
||||
}
|
||||
|
||||
void StringFieldGenerator::GenerateInlineAccessorDefinitions(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format(
|
||||
"inline const std::string& $classname$::$name$() const {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_get:$full_name$)\n");
|
||||
if (!descriptor_->default_value_string().empty()) {
|
||||
format(
|
||||
" if ($name$_.IsDefault(nullptr)) return "
|
||||
"$default_variable_name$.get();\n");
|
||||
}
|
||||
format(
|
||||
" return _internal_$name$();\n"
|
||||
"}\n"
|
||||
"inline void $classname$::set_$name$(const std::string& value) {\n"
|
||||
"$annotate_accessor$"
|
||||
" _internal_set_$name$(value);\n"
|
||||
" // @@protoc_insertion_point(field_set:$full_name$)\n"
|
||||
"}\n"
|
||||
"inline std::string* $classname$::mutable_$name$() {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_mutable:$full_name$)\n"
|
||||
" return _internal_mutable_$name$();\n"
|
||||
"}\n"
|
||||
"inline const std::string& $classname$::_internal_$name$() const {\n"
|
||||
" return $name$_.Get();\n"
|
||||
"}\n"
|
||||
"inline void $classname$::_internal_set_$name$(const std::string& "
|
||||
"value) {\n"
|
||||
" $set_hasbit$\n"
|
||||
" $name$_.Set($default_value_tag$, value, GetArena());\n"
|
||||
"}\n"
|
||||
"inline void $classname$::set_$name$(std::string&& value) {\n"
|
||||
"$annotate_accessor$"
|
||||
" $set_hasbit$\n"
|
||||
" $name$_.Set(\n"
|
||||
" $default_value_tag$, ::std::move(value), GetArena());\n"
|
||||
" // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n"
|
||||
"}\n"
|
||||
"inline void $classname$::set_$name$(const char* value) {\n"
|
||||
"$annotate_accessor$"
|
||||
" $null_check$"
|
||||
" $set_hasbit$\n"
|
||||
" $name$_.Set($default_value_tag$, $string_piece$(value), GetArena());\n"
|
||||
" // @@protoc_insertion_point(field_set_char:$full_name$)\n"
|
||||
"}\n");
|
||||
if (!options_.opensource_runtime) {
|
||||
format(
|
||||
"inline void $classname$::set_$name$(::StringPiece value) {\n"
|
||||
"$annotate_accessor$"
|
||||
" $set_hasbit$\n"
|
||||
" $name$_.Set($default_value_tag$, value,GetArena());\n"
|
||||
" // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n"
|
||||
"}\n");
|
||||
}
|
||||
format(
|
||||
"inline "
|
||||
"void $classname$::set_$name$(const $pointer_type$* value,\n"
|
||||
" size_t size) {\n"
|
||||
"$annotate_accessor$"
|
||||
" $set_hasbit$\n"
|
||||
" $name$_.Set($default_value_tag$, $string_piece$(\n"
|
||||
" reinterpret_cast<const char*>(value), size), GetArena());\n"
|
||||
" // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
|
||||
"}\n"
|
||||
"inline std::string* $classname$::_internal_mutable_$name$() {\n"
|
||||
" $set_hasbit$\n"
|
||||
" return $name$_.Mutable($default_variable_or_tag$, GetArena());\n"
|
||||
"}\n"
|
||||
"inline std::string* $classname$::$release_name$() {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_release:$full_name$)\n");
|
||||
|
||||
if (HasHasbit(descriptor_)) {
|
||||
format(
|
||||
" if (!_internal_has_$name$()) {\n"
|
||||
" return nullptr;\n"
|
||||
" }\n"
|
||||
" $clear_hasbit$\n"
|
||||
" return $name$_.ReleaseNonDefault($init_value$, GetArena());\n");
|
||||
} else {
|
||||
format(" return $name$_.Release($init_value$, GetArena());\n");
|
||||
}
|
||||
|
||||
format(
|
||||
"}\n"
|
||||
"inline void $classname$::set_allocated_$name$(std::string* $name$) {\n"
|
||||
"$annotate_accessor$"
|
||||
" if ($name$ != nullptr) {\n"
|
||||
" $set_hasbit$\n"
|
||||
" } else {\n"
|
||||
" $clear_hasbit$\n"
|
||||
" }\n"
|
||||
" $name$_.SetAllocated($init_value$, $name$,\n"
|
||||
" GetArena());\n"
|
||||
" // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
void StringFieldGenerator::GenerateNonInlineAccessorDefinitions(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
if (!descriptor_->default_value_string().empty()) {
|
||||
format(
|
||||
"const ::$proto_ns$::internal::LazyString "
|
||||
"$classname$::$default_variable_name$"
|
||||
"{{{$default$, $default_length$}}, {nullptr}};\n");
|
||||
}
|
||||
}
|
||||
|
||||
void StringFieldGenerator::GenerateClearingCode(io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
if (descriptor_->default_value_string().empty()) {
|
||||
format("$name$_.ClearToEmpty();\n");
|
||||
} else {
|
||||
format("$name$_.ClearToDefault($lazy_variable$, GetArena());\n");
|
||||
}
|
||||
}
|
||||
|
||||
void StringFieldGenerator::GenerateMessageClearingCode(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
// Two-dimension specialization here: supporting arenas, field presence, or
|
||||
// not, and default value is the empty string or not. Complexity here ensures
|
||||
// the minimal number of branches / amount of extraneous code at runtime
|
||||
// (given that the below methods are inlined one-liners)!
|
||||
|
||||
// If we have a hasbit, then the Clear() method of the protocol buffer
|
||||
// will have checked that this field is set. If so, we can avoid redundant
|
||||
// checks against the default variable.
|
||||
const bool must_be_present = HasHasbit(descriptor_);
|
||||
|
||||
if (descriptor_->default_value_string().empty()) {
|
||||
if (must_be_present) {
|
||||
format("$name$_.ClearNonDefaultToEmpty();\n");
|
||||
} else {
|
||||
format("$name$_.ClearToEmpty();\n");
|
||||
}
|
||||
} else {
|
||||
// Clear to a non-empty default is more involved, as we try to use the
|
||||
// Arena if one is present and may need to reallocate the string.
|
||||
format("$name$_.ClearToDefault($lazy_variable$, GetArena());\n ");
|
||||
}
|
||||
}
|
||||
|
||||
void StringFieldGenerator::GenerateMergingCode(io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
// TODO(gpike): improve this
|
||||
format("_internal_set_$name$(from._internal_$name$());\n");
|
||||
}
|
||||
|
||||
void StringFieldGenerator::GenerateSwappingCode(io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("$name$_.Swap(&other->$name$_, $init_value$, GetArena());\n");
|
||||
}
|
||||
|
||||
void StringFieldGenerator::GenerateConstructorCode(io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("$name$_.UnsafeSetDefault($init_value$);\n");
|
||||
}
|
||||
|
||||
void StringFieldGenerator::GenerateCopyConstructorCode(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
GenerateConstructorCode(printer);
|
||||
|
||||
if (HasHasbit(descriptor_)) {
|
||||
format("if (from._internal_has_$name$()) {\n");
|
||||
} else {
|
||||
format("if (!from._internal_$name$().empty()) {\n");
|
||||
}
|
||||
|
||||
format.Indent();
|
||||
|
||||
// TODO(gpike): improve this
|
||||
format(
|
||||
"$name$_.Set($default_value_tag$, from._internal_$name$(), \n"
|
||||
" GetArena());\n");
|
||||
|
||||
format.Outdent();
|
||||
format("}\n");
|
||||
}
|
||||
|
||||
void StringFieldGenerator::GenerateDestructorCode(io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("$name$_.DestroyNoArena($init_value$);\n");
|
||||
}
|
||||
|
||||
void StringFieldGenerator::GenerateSerializeWithCachedSizesToArray(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
|
||||
GenerateUtf8CheckCodeForString(
|
||||
descriptor_, options_, false,
|
||||
"this->_internal_$name$().data(), "
|
||||
"static_cast<int>(this->_internal_$name$().length()),\n",
|
||||
format);
|
||||
}
|
||||
format(
|
||||
"target = stream->Write$declared_type$MaybeAliased(\n"
|
||||
" $number$, this->_internal_$name$(), target);\n");
|
||||
}
|
||||
|
||||
void StringFieldGenerator::GenerateByteSize(io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format(
|
||||
"total_size += $tag_size$ +\n"
|
||||
" ::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n"
|
||||
" this->_internal_$name$());\n");
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
|
||||
StringOneofFieldGenerator::StringOneofFieldGenerator(
|
||||
const FieldDescriptor* descriptor, const Options& options)
|
||||
: StringFieldGenerator(descriptor, options) {
|
||||
SetCommonOneofFieldVariables(descriptor, &variables_);
|
||||
variables_["field_name"] = UnderscoresToCamelCase(descriptor->name(), true);
|
||||
variables_["oneof_index"] =
|
||||
StrCat(descriptor->containing_oneof()->index());
|
||||
}
|
||||
|
||||
StringOneofFieldGenerator::~StringOneofFieldGenerator() {}
|
||||
|
||||
void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format(
|
||||
"inline const std::string& $classname$::$name$() const {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_get:$full_name$)\n"
|
||||
" return _internal_$name$();\n"
|
||||
"}\n"
|
||||
"inline void $classname$::set_$name$(const std::string& value) {\n"
|
||||
"$annotate_accessor$"
|
||||
" _internal_set_$name$(value);\n"
|
||||
" // @@protoc_insertion_point(field_set:$full_name$)\n"
|
||||
"}\n"
|
||||
"inline std::string* $classname$::mutable_$name$() {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_mutable:$full_name$)\n"
|
||||
" return _internal_mutable_$name$();\n"
|
||||
"}\n"
|
||||
"inline const std::string& $classname$::_internal_$name$() const {\n"
|
||||
" if (_internal_has_$name$()) {\n"
|
||||
" return $field_member$.Get();\n"
|
||||
" }\n"
|
||||
" return $default_string$;\n"
|
||||
"}\n"
|
||||
"inline void $classname$::_internal_set_$name$(const std::string& "
|
||||
"value) {\n"
|
||||
" if (!_internal_has_$name$()) {\n"
|
||||
" clear_$oneof_name$();\n"
|
||||
" set_has_$name$();\n"
|
||||
" $field_member$.UnsafeSetDefault($init_value$);\n"
|
||||
" }\n"
|
||||
" $field_member$.Set($default_value_tag$, value, GetArena());\n"
|
||||
"}\n"
|
||||
"inline void $classname$::set_$name$(std::string&& value) {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_set:$full_name$)\n"
|
||||
" if (!_internal_has_$name$()) {\n"
|
||||
" clear_$oneof_name$();\n"
|
||||
" set_has_$name$();\n"
|
||||
" $field_member$.UnsafeSetDefault($init_value$);\n"
|
||||
" }\n"
|
||||
" $field_member$.Set(\n"
|
||||
" $default_value_tag$, ::std::move(value), GetArena());\n"
|
||||
" // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n"
|
||||
"}\n"
|
||||
"inline void $classname$::set_$name$(const char* value) {\n"
|
||||
"$annotate_accessor$"
|
||||
" $null_check$"
|
||||
" if (!_internal_has_$name$()) {\n"
|
||||
" clear_$oneof_name$();\n"
|
||||
" set_has_$name$();\n"
|
||||
" $field_member$.UnsafeSetDefault($init_value$);\n"
|
||||
" }\n"
|
||||
" $field_member$.Set($default_value_tag$,\n"
|
||||
" $string_piece$(value), GetArena());\n"
|
||||
" // @@protoc_insertion_point(field_set_char:$full_name$)\n"
|
||||
"}\n");
|
||||
if (!options_.opensource_runtime) {
|
||||
format(
|
||||
"inline void $classname$::set_$name$(::StringPiece value) {\n"
|
||||
"$annotate_accessor$"
|
||||
" if (!_internal_has_$name$()) {\n"
|
||||
" clear_$oneof_name$();\n"
|
||||
" set_has_$name$();\n"
|
||||
" $field_member$.UnsafeSetDefault($init_value$);\n"
|
||||
" }\n"
|
||||
" $field_member$.Set($default_value_tag$, value, GetArena());\n"
|
||||
" // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n"
|
||||
"}\n");
|
||||
}
|
||||
format(
|
||||
"inline "
|
||||
"void $classname$::set_$name$(const $pointer_type$* value,\n"
|
||||
" size_t size) {\n"
|
||||
"$annotate_accessor$"
|
||||
" if (!_internal_has_$name$()) {\n"
|
||||
" clear_$oneof_name$();\n"
|
||||
" set_has_$name$();\n"
|
||||
" $field_member$.UnsafeSetDefault($init_value$);\n"
|
||||
" }\n"
|
||||
" $field_member$.Set(\n"
|
||||
" $default_value_tag$, $string_piece$(\n"
|
||||
" reinterpret_cast<const char*>(value), size),\n"
|
||||
" GetArena());\n"
|
||||
" // @@protoc_insertion_point(field_set_pointer:$full_name$)\n"
|
||||
"}\n"
|
||||
"inline std::string* $classname$::_internal_mutable_$name$() {\n"
|
||||
" if (!_internal_has_$name$()) {\n"
|
||||
" clear_$oneof_name$();\n"
|
||||
" set_has_$name$();\n"
|
||||
" $field_member$.UnsafeSetDefault($init_value$);\n"
|
||||
" }\n"
|
||||
" return $field_member$.Mutable(\n"
|
||||
" $default_variable_or_tag$, GetArena());\n"
|
||||
"}\n"
|
||||
"inline std::string* $classname$::$release_name$() {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_release:$full_name$)\n"
|
||||
" if (_internal_has_$name$()) {\n"
|
||||
" clear_has_$oneof_name$();\n"
|
||||
" return $field_member$.ReleaseNonDefault($init_value$, GetArena());\n"
|
||||
" } else {\n"
|
||||
" return nullptr;\n"
|
||||
" }\n"
|
||||
"}\n"
|
||||
"inline void $classname$::set_allocated_$name$(std::string* $name$) {\n"
|
||||
"$annotate_accessor$"
|
||||
" if (has_$oneof_name$()) {\n"
|
||||
" clear_$oneof_name$();\n"
|
||||
" }\n"
|
||||
" if ($name$ != nullptr) {\n"
|
||||
" set_has_$name$();\n"
|
||||
" $field_member$.UnsafeSetDefault($name$);\n"
|
||||
" ::$proto_ns$::Arena* arena = GetArena();\n"
|
||||
" if (arena != nullptr) {\n"
|
||||
" arena->Own($name$);\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
void StringOneofFieldGenerator::GenerateClearingCode(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("$field_member$.Destroy($default_value_tag$, GetArena());\n");
|
||||
}
|
||||
|
||||
void StringOneofFieldGenerator::GenerateMessageClearingCode(
|
||||
io::Printer* printer) const {
|
||||
return GenerateClearingCode(printer);
|
||||
}
|
||||
|
||||
void StringOneofFieldGenerator::GenerateSwappingCode(
|
||||
io::Printer* printer) const {
|
||||
// Don't print any swapping code. Swapping the union will swap this field.
|
||||
}
|
||||
|
||||
void StringOneofFieldGenerator::GenerateConstructorCode(
|
||||
io::Printer* printer) const {
|
||||
// Nothing required here.
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
|
||||
RepeatedStringFieldGenerator::RepeatedStringFieldGenerator(
|
||||
const FieldDescriptor* descriptor, const Options& options)
|
||||
: FieldGenerator(descriptor, options) {
|
||||
SetStringVariables(descriptor, &variables_, options);
|
||||
}
|
||||
|
||||
RepeatedStringFieldGenerator::~RepeatedStringFieldGenerator() {}
|
||||
|
||||
void RepeatedStringFieldGenerator::GeneratePrivateMembers(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("::$proto_ns$::RepeatedPtrField<std::string> $name$_;\n");
|
||||
}
|
||||
|
||||
void RepeatedStringFieldGenerator::GenerateAccessorDeclarations(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
// See comment above about unknown ctypes.
|
||||
bool unknown_ctype = descriptor_->options().ctype() !=
|
||||
EffectiveStringCType(descriptor_, options_);
|
||||
|
||||
if (unknown_ctype) {
|
||||
format.Outdent();
|
||||
format(
|
||||
" private:\n"
|
||||
" // Hidden due to unknown ctype option.\n");
|
||||
format.Indent();
|
||||
}
|
||||
|
||||
format(
|
||||
"$deprecated_attr$const std::string& ${1$$name$$}$(int index) const;\n"
|
||||
"$deprecated_attr$std::string* ${1$mutable_$name$$}$(int index);\n"
|
||||
"$deprecated_attr$void ${1$set_$name$$}$(int index, const "
|
||||
"std::string& value);\n"
|
||||
"$deprecated_attr$void ${1$set_$name$$}$(int index, std::string&& "
|
||||
"value);\n"
|
||||
"$deprecated_attr$void ${1$set_$name$$}$(int index, const "
|
||||
"char* value);\n",
|
||||
descriptor_);
|
||||
if (!options_.opensource_runtime) {
|
||||
format(
|
||||
"$deprecated_attr$void ${1$set_$name$$}$(int index, "
|
||||
"StringPiece value);\n",
|
||||
descriptor_);
|
||||
}
|
||||
format(
|
||||
"$deprecated_attr$void ${1$set_$name$$}$("
|
||||
"int index, const $pointer_type$* value, size_t size);\n"
|
||||
"$deprecated_attr$std::string* ${1$add_$name$$}$();\n"
|
||||
"$deprecated_attr$void ${1$add_$name$$}$(const std::string& value);\n"
|
||||
"$deprecated_attr$void ${1$add_$name$$}$(std::string&& value);\n"
|
||||
"$deprecated_attr$void ${1$add_$name$$}$(const char* value);\n",
|
||||
descriptor_);
|
||||
if (!options_.opensource_runtime) {
|
||||
format(
|
||||
"$deprecated_attr$void ${1$add_$name$$}$(StringPiece value);\n",
|
||||
descriptor_);
|
||||
}
|
||||
format(
|
||||
"$deprecated_attr$void ${1$add_$name$$}$(const $pointer_type$* "
|
||||
"value, size_t size)"
|
||||
";\n"
|
||||
"$deprecated_attr$const ::$proto_ns$::RepeatedPtrField<std::string>& "
|
||||
"${1$$name$$}$() "
|
||||
"const;\n"
|
||||
"$deprecated_attr$::$proto_ns$::RepeatedPtrField<std::string>* "
|
||||
"${1$mutable_$name$$}$()"
|
||||
";\n"
|
||||
"private:\n"
|
||||
"const std::string& ${1$_internal_$name$$}$(int index) const;\n"
|
||||
"std::string* _internal_add_$name$();\n"
|
||||
"public:\n",
|
||||
descriptor_);
|
||||
|
||||
if (unknown_ctype) {
|
||||
format.Outdent();
|
||||
format(" public:\n");
|
||||
format.Indent();
|
||||
}
|
||||
}
|
||||
|
||||
void RepeatedStringFieldGenerator::GenerateInlineAccessorDefinitions(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format(
|
||||
"inline std::string* $classname$::add_$name$() {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_add_mutable:$full_name$)\n"
|
||||
" return _internal_add_$name$();\n"
|
||||
"}\n");
|
||||
if (options_.safe_boundary_check) {
|
||||
format(
|
||||
"inline const std::string& $classname$::_internal_$name$(int index) "
|
||||
"const {\n"
|
||||
" return $name$_.InternalCheckedGet(\n"
|
||||
" index, ::$proto_ns$::internal::GetEmptyStringAlreadyInited());\n"
|
||||
"}\n");
|
||||
} else {
|
||||
format(
|
||||
"inline const std::string& $classname$::_internal_$name$(int index) "
|
||||
"const {\n"
|
||||
" return $name$_.Get(index);\n"
|
||||
"}\n");
|
||||
}
|
||||
format(
|
||||
"inline const std::string& $classname$::$name$(int index) const {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_get:$full_name$)\n"
|
||||
" return _internal_$name$(index);\n"
|
||||
"}\n"
|
||||
"inline std::string* $classname$::mutable_$name$(int index) {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@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"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_set:$full_name$)\n"
|
||||
" $name$_.Mutable(index)->assign(value);\n"
|
||||
"}\n"
|
||||
"inline void $classname$::set_$name$(int index, std::string&& value) {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_set:$full_name$)\n"
|
||||
" $name$_.Mutable(index)->assign(std::move(value));\n"
|
||||
"}\n"
|
||||
"inline void $classname$::set_$name$(int index, const char* value) {\n"
|
||||
"$annotate_accessor$"
|
||||
" $null_check$"
|
||||
" $name$_.Mutable(index)->assign(value);\n"
|
||||
" // @@protoc_insertion_point(field_set_char:$full_name$)\n"
|
||||
"}\n");
|
||||
if (!options_.opensource_runtime) {
|
||||
format(
|
||||
"inline void "
|
||||
"$classname$::set_$name$(int index, StringPiece value) {\n"
|
||||
"$annotate_accessor$"
|
||||
" $name$_.Mutable(index)->assign(value.data(), value.size());\n"
|
||||
" // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n"
|
||||
"}\n");
|
||||
}
|
||||
format(
|
||||
"inline void "
|
||||
"$classname$::set_$name$"
|
||||
"(int index, const $pointer_type$* value, size_t size) {\n"
|
||||
"$annotate_accessor$"
|
||||
" $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$::_internal_add_$name$() {\n"
|
||||
" return $name$_.Add();\n"
|
||||
"}\n"
|
||||
"inline void $classname$::add_$name$(const std::string& value) {\n"
|
||||
"$annotate_accessor$"
|
||||
" $name$_.Add()->assign(value);\n"
|
||||
" // @@protoc_insertion_point(field_add:$full_name$)\n"
|
||||
"}\n"
|
||||
"inline void $classname$::add_$name$(std::string&& value) {\n"
|
||||
"$annotate_accessor$"
|
||||
" $name$_.Add(std::move(value));\n"
|
||||
" // @@protoc_insertion_point(field_add:$full_name$)\n"
|
||||
"}\n"
|
||||
"inline void $classname$::add_$name$(const char* value) {\n"
|
||||
"$annotate_accessor$"
|
||||
" $null_check$"
|
||||
" $name$_.Add()->assign(value);\n"
|
||||
" // @@protoc_insertion_point(field_add_char:$full_name$)\n"
|
||||
"}\n");
|
||||
if (!options_.opensource_runtime) {
|
||||
format(
|
||||
"inline void $classname$::add_$name$(StringPiece value) {\n"
|
||||
"$annotate_accessor$"
|
||||
" $name$_.Add()->assign(value.data(), value.size());\n"
|
||||
" // @@protoc_insertion_point(field_add_string_piece:$full_name$)\n"
|
||||
"}\n");
|
||||
}
|
||||
format(
|
||||
"inline void "
|
||||
"$classname$::add_$name$(const $pointer_type$* value, size_t size) {\n"
|
||||
"$annotate_accessor$"
|
||||
" $name$_.Add()->assign(reinterpret_cast<const char*>(value), size);\n"
|
||||
" // @@protoc_insertion_point(field_add_pointer:$full_name$)\n"
|
||||
"}\n"
|
||||
"inline const ::$proto_ns$::RepeatedPtrField<std::string>&\n"
|
||||
"$classname$::$name$() const {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_list:$full_name$)\n"
|
||||
" return $name$_;\n"
|
||||
"}\n"
|
||||
"inline ::$proto_ns$::RepeatedPtrField<std::string>*\n"
|
||||
"$classname$::mutable_$name$() {\n"
|
||||
"$annotate_accessor$"
|
||||
" // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
|
||||
" return &$name$_;\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
void RepeatedStringFieldGenerator::GenerateClearingCode(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("$name$_.Clear();\n");
|
||||
}
|
||||
|
||||
void RepeatedStringFieldGenerator::GenerateMergingCode(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("$name$_.MergeFrom(from.$name$_);\n");
|
||||
}
|
||||
|
||||
void RepeatedStringFieldGenerator::GenerateSwappingCode(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("$name$_.InternalSwap(&other->$name$_);\n");
|
||||
}
|
||||
|
||||
void RepeatedStringFieldGenerator::GenerateConstructorCode(
|
||||
io::Printer* printer) const {
|
||||
// Not needed for repeated fields.
|
||||
}
|
||||
|
||||
void RepeatedStringFieldGenerator::GenerateCopyConstructorCode(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format("$name$_.CopyFrom(from.$name$_);");
|
||||
}
|
||||
|
||||
void RepeatedStringFieldGenerator::GenerateSerializeWithCachedSizesToArray(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format(
|
||||
"for (int i = 0, n = this->_internal_$name$_size(); i < n; i++) {\n"
|
||||
" const auto& s = this->_internal_$name$(i);\n");
|
||||
// format("for (const std::string& s : this->$name$()) {\n");
|
||||
format.Indent();
|
||||
if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
|
||||
GenerateUtf8CheckCodeForString(descriptor_, options_, false,
|
||||
"s.data(), static_cast<int>(s.length()),\n",
|
||||
format);
|
||||
}
|
||||
format.Outdent();
|
||||
format(
|
||||
" target = stream->Write$declared_type$($number$, s, target);\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
void RepeatedStringFieldGenerator::GenerateByteSize(
|
||||
io::Printer* printer) const {
|
||||
Formatter format(printer, variables_);
|
||||
format(
|
||||
"total_size += $tag_size$ *\n"
|
||||
" ::$proto_ns$::internal::FromIntSize($name$_.size());\n"
|
||||
"for (int i = 0, n = $name$_.size(); i < n; i++) {\n"
|
||||
" total_size += "
|
||||
"::$proto_ns$::internal::WireFormatLite::$declared_type$Size(\n"
|
||||
" $name$_.Get(i));\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
120
ubuntu/google/protobuf/compiler/cpp/cpp_string_field.h
Normal file
120
ubuntu/google/protobuf/compiler/cpp/cpp_string_field.h
Normal file
@@ -0,0 +1,120 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// 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:
|
||||
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 GenerateMessageClearingCode(io::Printer* printer) const;
|
||||
void GenerateMergingCode(io::Printer* printer) const;
|
||||
void GenerateSwappingCode(io::Printer* printer) const;
|
||||
void GenerateConstructorCode(io::Printer* printer) const;
|
||||
void GenerateCopyConstructorCode(io::Printer* printer) const;
|
||||
void GenerateDestructorCode(io::Printer* printer) const;
|
||||
void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
|
||||
void GenerateByteSize(io::Printer* printer) const;
|
||||
|
||||
private:
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringFieldGenerator);
|
||||
};
|
||||
|
||||
class StringOneofFieldGenerator : public StringFieldGenerator {
|
||||
public:
|
||||
StringOneofFieldGenerator(const FieldDescriptor* descriptor,
|
||||
const Options& options);
|
||||
~StringOneofFieldGenerator();
|
||||
|
||||
// implements FieldGenerator ---------------------------------------
|
||||
void GenerateInlineAccessorDefinitions(io::Printer* printer) const;
|
||||
void GenerateClearingCode(io::Printer* printer) const;
|
||||
|
||||
// StringFieldGenerator, from which we inherit, overrides this so we need to
|
||||
// override it as well.
|
||||
void GenerateMessageClearingCode(io::Printer* printer) const;
|
||||
void GenerateSwappingCode(io::Printer* printer) const;
|
||||
void GenerateConstructorCode(io::Printer* printer) const;
|
||||
|
||||
private:
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringOneofFieldGenerator);
|
||||
};
|
||||
|
||||
class RepeatedStringFieldGenerator : public FieldGenerator {
|
||||
public:
|
||||
RepeatedStringFieldGenerator(const FieldDescriptor* descriptor,
|
||||
const Options& options);
|
||||
~RepeatedStringFieldGenerator();
|
||||
|
||||
// implements FieldGenerator ---------------------------------------
|
||||
void GeneratePrivateMembers(io::Printer* printer) const;
|
||||
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 GenerateCopyConstructorCode(io::Printer* printer) const;
|
||||
void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const;
|
||||
void GenerateByteSize(io::Printer* printer) const;
|
||||
|
||||
private:
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedStringFieldGenerator);
|
||||
};
|
||||
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_CPP_STRING_FIELD_H__
|
||||
@@ -0,0 +1,184 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Author: kenton@google.com (Kenton Varda)
|
||||
// Based on original Protocol Buffers design by
|
||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||
//
|
||||
// This file tests that various identifiers work as field and type names even
|
||||
// though the same identifiers are used internally by the C++ code generator.
|
||||
|
||||
// LINT: LEGACY_NAMES
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
// Some generic_services option(s) added automatically.
|
||||
// See: http://go/proto2-generic-services-default
|
||||
option cc_generic_services = true; // auto-added
|
||||
|
||||
// We don't put this in a package within proto2 because we need to make sure
|
||||
// that the generated code doesn't depend on being in the proto2 namespace.
|
||||
package protobuf_unittest;
|
||||
|
||||
// Test that fields can have names like "input" and "i" which are also used
|
||||
// internally by the code generator for local variables.
|
||||
message TestConflictingSymbolNames {
|
||||
message BuildDescriptors {}
|
||||
message TypeTraits {}
|
||||
|
||||
optional int32 input = 1;
|
||||
optional int32 output = 2;
|
||||
optional string length = 3;
|
||||
repeated int32 i = 4;
|
||||
repeated string new_element = 5 [ctype = STRING_PIECE];
|
||||
optional int32 total_size = 6;
|
||||
optional int32 tag = 7;
|
||||
|
||||
enum TestEnum { FOO = 0; }
|
||||
message Data1 {
|
||||
repeated int32 data = 1;
|
||||
}
|
||||
message Data2 {
|
||||
repeated TestEnum data = 1;
|
||||
}
|
||||
message Data3 {
|
||||
repeated string data = 1;
|
||||
}
|
||||
message Data4 {
|
||||
repeated Data4 data = 1;
|
||||
}
|
||||
message Data5 {
|
||||
repeated string data = 1 [ctype = STRING_PIECE];
|
||||
}
|
||||
message Data6 {
|
||||
repeated string data = 1 [ctype = CORD];
|
||||
}
|
||||
|
||||
optional int32 source = 8;
|
||||
optional int32 value = 9;
|
||||
optional int32 file = 10;
|
||||
optional int32 from = 11;
|
||||
optional int32 handle_uninterpreted = 12;
|
||||
repeated int32 index = 13;
|
||||
optional int32 controller = 14;
|
||||
optional int32 already_here = 15;
|
||||
|
||||
optional uint32 uint32 = 16;
|
||||
optional uint64 uint64 = 17;
|
||||
optional string string = 18;
|
||||
optional int32 memset = 19;
|
||||
optional int32 int32 = 20;
|
||||
optional int64 int64 = 21;
|
||||
|
||||
optional uint32 cached_size = 22;
|
||||
optional uint32 extensions = 23;
|
||||
optional uint32 bit = 24;
|
||||
optional uint32 bits = 25;
|
||||
optional uint32 offsets = 26;
|
||||
optional uint32 reflection = 27;
|
||||
|
||||
message Cord {}
|
||||
optional string some_cord = 28 [ctype = CORD];
|
||||
|
||||
message StringPiece {}
|
||||
optional string some_string_piece = 29 [ctype = STRING_PIECE];
|
||||
|
||||
// Some keywords.
|
||||
optional uint32 int = 30;
|
||||
optional uint32 friend = 31;
|
||||
optional uint32 class = 37;
|
||||
optional uint32 typedecl = 39;
|
||||
optional uint32 auto = 40;
|
||||
|
||||
// The generator used to #define a macro called "DO" inside the .cc file.
|
||||
message DO {}
|
||||
optional DO do = 32;
|
||||
|
||||
// Some template parameter names for extensions.
|
||||
optional int32 field_type = 33;
|
||||
optional bool is_packed = 34;
|
||||
|
||||
// test conflicting release_$name$. "length" and "do" field in this message
|
||||
// must remain string or message fields to make the test valid.
|
||||
optional string release_length = 35;
|
||||
// A more extreme case, the field name "do" here is a keyword, which will be
|
||||
// escaped to "do_" already. Test there is no conflict even with escaped field
|
||||
// names.
|
||||
optional DO release_do = 36;
|
||||
|
||||
// For clashing local variables in Serialize and ByteSize calculation.
|
||||
optional string target = 38;
|
||||
|
||||
extensions 1000 to max; // NO_PROTO3
|
||||
}
|
||||
|
||||
message TestConflictingSymbolNamesExtension { // NO_PROTO3
|
||||
extend TestConflictingSymbolNames { // NO_PROTO3
|
||||
repeated int32 repeated_int32_ext = 20423638 [packed = true]; // NO_PROTO3
|
||||
} // NO_PROTO3
|
||||
} // NO_PROTO3
|
||||
|
||||
message TestConflictingEnumNames { // NO_PROTO3
|
||||
enum while { // NO_PROTO3
|
||||
default = 0; // NO_PROTO3
|
||||
and = 1; // NO_PROTO3
|
||||
class = 2; // NO_PROTO3
|
||||
int = 3; // NO_PROTO3
|
||||
typedef = 4; // NO_PROTO3
|
||||
XOR = 5; // NO_PROTO3
|
||||
} // NO_PROTO3
|
||||
|
||||
optional while conflicting_enum = 1; // NO_PROTO3
|
||||
} // NO_PROTO3
|
||||
|
||||
enum bool { // NO_PROTO3
|
||||
default = 0; // NO_PROTO3
|
||||
NOT_EQ = 1; // NO_PROTO3
|
||||
volatile = 2; // NO_PROTO3
|
||||
return = 3; // NO_PROTO3
|
||||
} // NO_PROTO3
|
||||
|
||||
message DummyMessage {}
|
||||
|
||||
message NULL {
|
||||
optional int32 int = 1;
|
||||
}
|
||||
|
||||
extend TestConflictingSymbolNames { // NO_PROTO3
|
||||
optional int32 void = 314253; // NO_PROTO3
|
||||
} // NO_PROTO3
|
||||
|
||||
// Message names that could conflict.
|
||||
message Shutdown {}
|
||||
message TableStruct {}
|
||||
|
||||
service TestConflictingMethodNames {
|
||||
rpc Closure(DummyMessage) returns (DummyMessage);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Test that proto2 compiler can generate valid code when the enum value
|
||||
// is INT_MAX. Note that this is a compile-only test and this proto is not
|
||||
// referenced in any C++ code.
|
||||
syntax = "proto2";
|
||||
|
||||
package protobuf_unittest;
|
||||
|
||||
message TestLargeEnumValue {
|
||||
enum EnumWithLargeValue {
|
||||
VALUE_1 = 1;
|
||||
VALUE_MAX = 0x7fffffff;
|
||||
}
|
||||
}
|
||||
134
ubuntu/google/protobuf/compiler/cpp/cpp_unittest.cc
Normal file
134
ubuntu/google/protobuf/compiler/cpp/cpp_unittest.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)
|
||||
// Based on original Protocol Buffers design by
|
||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||
//
|
||||
// To test the code generator, we actually use it to generate code for
|
||||
// net/proto2/internal/unittest.proto, then test that. This means that we
|
||||
// are actually testing the parser and other parts of the system at the same
|
||||
// time, and that problems in the generator may show up as compile-time errors
|
||||
// rather than unittest failures, which may be surprising. However, testing
|
||||
// the output of the C++ generator directly would be very hard. We can't very
|
||||
// well just check it against golden files since those files would have to be
|
||||
// updated for any small change; such a test would be very brittle and probably
|
||||
// not very helpful. What we really want to test is that the code compiles
|
||||
// correctly and produces the interfaces we expect, which is why this test
|
||||
// is written this way.
|
||||
|
||||
#include <google/protobuf/compiler/cpp/cpp_unittest.h>
|
||||
|
||||
#include <google/protobuf/unittest.pb.h>
|
||||
#include <google/protobuf/unittest_embed_optimize_for.pb.h>
|
||||
#include <google/protobuf/unittest_optimize_for.pb.h>
|
||||
|
||||
#include <google/protobuf/test_util.h>
|
||||
|
||||
#define MESSAGE_TEST_NAME MessageTest
|
||||
#define GENERATED_DESCRIPTOR_TEST_NAME GeneratedDescriptorTest
|
||||
#define GENERATED_MESSAGE_TEST_NAME GeneratedMessageTest
|
||||
#define GENERATED_ENUM_TEST_NAME GeneratedEnumTest
|
||||
#define GENERATED_SERVICE_TEST_NAME GeneratedServiceTest
|
||||
#define HELPERS_TEST_NAME HelpersTest
|
||||
#define DESCRIPTOR_INIT_TEST_NAME DescriptorInitializationTest
|
||||
|
||||
#define UNITTEST_PROTO_PATH "net/proto2/internal/unittest.proto"
|
||||
#define UNITTEST ::protobuf_unittest
|
||||
#define UNITTEST_IMPORT ::protobuf_unittest_import
|
||||
|
||||
// Must include after the above macros.
|
||||
#include <google/protobuf/compiler/cpp/cpp_unittest.inc>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace cpp {
|
||||
|
||||
// Can't use an anonymous namespace here due to brokenness of Tru64 compiler.
|
||||
namespace cpp_unittest {
|
||||
|
||||
namespace protobuf_unittest = ::protobuf_unittest;
|
||||
|
||||
TEST(GENERATED_MESSAGE_TEST_NAME, TestConflictingSymbolNames) {
|
||||
// test_bad_identifiers.proto successfully compiled, then it works. The
|
||||
// following is just a token usage to insure that the code is, in fact,
|
||||
// being compiled and linked.
|
||||
|
||||
protobuf_unittest::TestConflictingSymbolNames message;
|
||||
message.set_uint32(1);
|
||||
EXPECT_EQ(3, message.ByteSizeLong());
|
||||
|
||||
message.set_friend_(5);
|
||||
EXPECT_EQ(5, message.friend_());
|
||||
|
||||
message.set_class_(6);
|
||||
EXPECT_EQ(6, message.class_());
|
||||
|
||||
// Instantiate extension template functions to test conflicting template
|
||||
// parameter names.
|
||||
typedef protobuf_unittest::TestConflictingSymbolNamesExtension ExtensionMessage;
|
||||
message.AddExtension(ExtensionMessage::repeated_int32_ext, 123);
|
||||
EXPECT_EQ(123, message.GetExtension(ExtensionMessage::repeated_int32_ext, 0));
|
||||
}
|
||||
|
||||
TEST(GENERATED_MESSAGE_TEST_NAME, TestConflictingEnumNames) {
|
||||
protobuf_unittest::TestConflictingEnumNames message;
|
||||
message.set_conflicting_enum(
|
||||
protobuf_unittest::TestConflictingEnumNames_while_and_);
|
||||
EXPECT_EQ(1, message.conflicting_enum());
|
||||
message.set_conflicting_enum(
|
||||
protobuf_unittest::TestConflictingEnumNames_while_XOR);
|
||||
EXPECT_EQ(5, message.conflicting_enum());
|
||||
|
||||
protobuf_unittest::bool_ conflicting_enum;
|
||||
conflicting_enum = protobuf_unittest::NOT_EQ;
|
||||
EXPECT_EQ(1, conflicting_enum);
|
||||
conflicting_enum = protobuf_unittest::return_;
|
||||
EXPECT_EQ(3, conflicting_enum);
|
||||
}
|
||||
|
||||
TEST(GENERATED_MESSAGE_TEST_NAME, TestConflictingMessageNames) {
|
||||
protobuf_unittest::NULL_ message;
|
||||
message.set_int_(123);
|
||||
EXPECT_EQ(message.int_(), 123);
|
||||
}
|
||||
|
||||
TEST(GENERATED_MESSAGE_TEST_NAME, TestConflictingExtension) {
|
||||
protobuf_unittest::TestConflictingSymbolNames message;
|
||||
message.SetExtension(protobuf_unittest::void_, 123);
|
||||
EXPECT_EQ(123, message.GetExtension(protobuf_unittest::void_));
|
||||
}
|
||||
|
||||
} // namespace cpp_unittest
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
51
ubuntu/google/protobuf/compiler/cpp/cpp_unittest.h
Normal file
51
ubuntu/google/protobuf/compiler/cpp/cpp_unittest.h
Normal file
@@ -0,0 +1,51 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// This header declares the namespace google::protobuf::protobuf_unittest in order to expose
|
||||
// any problems with the generated class names. We use this header to ensure
|
||||
// unittest.cc will declare the namespace prior to other includes, while obeying
|
||||
// normal include ordering.
|
||||
//
|
||||
// When generating a class name of "foo.Bar" we must ensure we prefix the class
|
||||
// name with "::", in case the namespace google::protobuf::foo exists. We intentionally
|
||||
// trigger that case here by declaring google::protobuf::protobuf_unittest.
|
||||
//
|
||||
// See ClassName in helpers.h for more details.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_UNITTEST_H__
|
||||
#define GOOGLE_PROTOBUF_COMPILER_CPP_UNITTEST_H__
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace protobuf_unittest {}
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_CPP_UNITTEST_H__
|
||||
2231
ubuntu/google/protobuf/compiler/cpp/cpp_unittest.inc
Normal file
2231
ubuntu/google/protobuf/compiler/cpp/cpp_unittest.inc
Normal file
File diff suppressed because it is too large
Load Diff
162
ubuntu/google/protobuf/compiler/cpp/metadata_test.cc
Normal file
162
ubuntu/google/protobuf/compiler/cpp/metadata_test.cc
Normal file
@@ -0,0 +1,162 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
|
||||
#include <google/protobuf/compiler/cpp/cpp_generator.h>
|
||||
#include <google/protobuf/compiler/annotation_test_util.h>
|
||||
#include <google/protobuf/compiler/command_line_interface.h>
|
||||
#include <google/protobuf/descriptor.pb.h>
|
||||
|
||||
#include <google/protobuf/testing/file.h>
|
||||
#include <google/protobuf/testing/file.h>
|
||||
#include <google/protobuf/testing/googletest.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace cpp {
|
||||
|
||||
namespace atu = annotation_test_util;
|
||||
|
||||
namespace {
|
||||
|
||||
class CppMetadataTest : public ::testing::Test {
|
||||
public:
|
||||
// Tries to capture a FileDescriptorProto, GeneratedCodeInfo, and output
|
||||
// code from the previously added file with name `filename`. Returns true on
|
||||
// success. If pb_h is non-null, expects a .pb.h and a .pb.h.meta (copied to
|
||||
// pb_h and pb_h_info respecfively); similarly for proto_h and proto_h_info.
|
||||
bool CaptureMetadata(const std::string& filename, FileDescriptorProto* file,
|
||||
std::string* pb_h, GeneratedCodeInfo* pb_h_info,
|
||||
std::string* proto_h, GeneratedCodeInfo* proto_h_info,
|
||||
std::string* pb_cc) {
|
||||
CommandLineInterface cli;
|
||||
CppGenerator cpp_generator;
|
||||
cli.RegisterGenerator("--cpp_out", &cpp_generator, "");
|
||||
std::string cpp_out =
|
||||
"--cpp_out=annotate_headers=true,"
|
||||
"annotation_pragma_name=pragma_name,"
|
||||
"annotation_guard_name=guard_name:" +
|
||||
TestTempDir();
|
||||
|
||||
const bool result = atu::RunProtoCompiler(filename, cpp_out, &cli, file);
|
||||
|
||||
if (!result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string output_base = TestTempDir() + "/" + StripProto(filename);
|
||||
|
||||
if (pb_cc != NULL) {
|
||||
GOOGLE_CHECK_OK(
|
||||
File::GetContents(output_base + ".pb.cc", pb_cc, true));
|
||||
}
|
||||
|
||||
if (pb_h != NULL && pb_h_info != NULL) {
|
||||
GOOGLE_CHECK_OK(
|
||||
File::GetContents(output_base + ".pb.h", pb_h, true));
|
||||
if (!atu::DecodeMetadata(output_base + ".pb.h.meta", pb_h_info)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (proto_h != NULL && proto_h_info != NULL) {
|
||||
GOOGLE_CHECK_OK(File::GetContents(output_base + ".proto.h", proto_h,
|
||||
true));
|
||||
if (!atu::DecodeMetadata(output_base + ".proto.h.meta", proto_h_info)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
const char kSmallTestFile[] =
|
||||
"syntax = \"proto2\";\n"
|
||||
"package foo;\n"
|
||||
"enum Enum { VALUE = 0; }\n"
|
||||
"message Message { }\n";
|
||||
|
||||
TEST_F(CppMetadataTest, CapturesEnumNames) {
|
||||
FileDescriptorProto file;
|
||||
GeneratedCodeInfo info;
|
||||
std::string pb_h;
|
||||
atu::AddFile("test.proto", kSmallTestFile);
|
||||
EXPECT_TRUE(
|
||||
CaptureMetadata("test.proto", &file, &pb_h, &info, NULL, NULL, NULL));
|
||||
EXPECT_EQ("Enum", file.enum_type(0).name());
|
||||
std::vector<int> enum_path;
|
||||
enum_path.push_back(FileDescriptorProto::kEnumTypeFieldNumber);
|
||||
enum_path.push_back(0);
|
||||
const GeneratedCodeInfo::Annotation* enum_annotation =
|
||||
atu::FindAnnotationOnPath(info, "test.proto", enum_path);
|
||||
EXPECT_TRUE(NULL != enum_annotation);
|
||||
EXPECT_TRUE(atu::AnnotationMatchesSubstring(pb_h, enum_annotation, "Enum"));
|
||||
}
|
||||
|
||||
TEST_F(CppMetadataTest, AddsPragma) {
|
||||
FileDescriptorProto file;
|
||||
GeneratedCodeInfo info;
|
||||
std::string pb_h;
|
||||
atu::AddFile("test.proto", kSmallTestFile);
|
||||
EXPECT_TRUE(
|
||||
CaptureMetadata("test.proto", &file, &pb_h, &info, NULL, NULL, NULL));
|
||||
EXPECT_TRUE(pb_h.find("#ifdef guard_name") != std::string::npos);
|
||||
EXPECT_TRUE(pb_h.find("#pragma pragma_name \"test.pb.h.meta\"") !=
|
||||
std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F(CppMetadataTest, CapturesMessageNames) {
|
||||
FileDescriptorProto file;
|
||||
GeneratedCodeInfo info;
|
||||
std::string pb_h;
|
||||
atu::AddFile("test.proto", kSmallTestFile);
|
||||
EXPECT_TRUE(
|
||||
CaptureMetadata("test.proto", &file, &pb_h, &info, NULL, NULL, NULL));
|
||||
EXPECT_EQ("Message", file.message_type(0).name());
|
||||
std::vector<int> message_path;
|
||||
message_path.push_back(FileDescriptorProto::kMessageTypeFieldNumber);
|
||||
message_path.push_back(0);
|
||||
const GeneratedCodeInfo::Annotation* message_annotation =
|
||||
atu::FindAnnotationOnPath(info, "test.proto", message_path);
|
||||
EXPECT_TRUE(NULL != message_annotation);
|
||||
EXPECT_TRUE(
|
||||
atu::AnnotationMatchesSubstring(pb_h, message_annotation, "Message"));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace cpp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
Reference in New Issue
Block a user