diff options
author | Adam Cozzette <acozzette@google.com> | 2017-09-12 10:32:01 -0700 |
---|---|---|
committer | Adam Cozzette <acozzette@google.com> | 2017-09-14 10:03:57 -0700 |
commit | 13fd045dbb2b4dacea32be162a41d5a4b0d1802f (patch) | |
tree | c219e7eb18b82523e36c6748861c403a14ea66ae /src/google/protobuf/compiler/cpp/cpp_helpers.cc | |
parent | d1bc27caef8377a710370189675cb0958443e8f1 (diff) | |
download | protobuf-13fd045dbb2b4dacea32be162a41d5a4b0d1802f.tar.gz protobuf-13fd045dbb2b4dacea32be162a41d5a4b0d1802f.tar.bz2 protobuf-13fd045dbb2b4dacea32be162a41d5a4b0d1802f.zip |
Integrated internal changes from Google
Diffstat (limited to 'src/google/protobuf/compiler/cpp/cpp_helpers.cc')
-rw-r--r-- | src/google/protobuf/compiler/cpp/cpp_helpers.cc | 223 |
1 files changed, 180 insertions, 43 deletions
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc index 00959796..4aa77d06 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc @@ -32,10 +32,11 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. +#include <google/protobuf/stubs/hash.h> #include <limits> #include <map> +#include <queue> #include <vector> -#include <google/protobuf/stubs/hash.h> #include <google/protobuf/stubs/logging.h> #include <google/protobuf/stubs/common.h> @@ -105,6 +106,30 @@ bool HasExtension(const Descriptor* descriptor) { return false; } +// Encode [0..63] as 'A'-'Z', 'a'-'z', '0'-'9', '_' +char Base63Char(int value) { + GOOGLE_CHECK_GE(value, 0); + if (value < 26) return 'A' + value; + value -= 26; + if (value < 26) return 'a' + value; + value -= 26; + if (value < 10) return '0' + value; + GOOGLE_CHECK_EQ(value, 10); + return '_'; +} + +// Given a c identifier has 63 legal characters we can't implement base64 +// encoding. So we return the k least significant "digits" in base 63. +template <typename I> +string Base63(I n, int k) { + string res; + while (k-- > 0) { + res += Base63Char(static_cast<int>(n % 63)); + n /= 63; + } + return res; +} + } // namespace string UnderscoresToCamelCase(const string& input, bool cap_next_letter) { @@ -137,44 +162,63 @@ const char kThickSeparator[] = const char kThinSeparator[] = "// -------------------------------------------------------------------\n"; -string ClassName(const Descriptor* descriptor, bool qualified) { - - // Find "outer", the descriptor of the top-level message in which - // "descriptor" is embedded. - const Descriptor* outer = descriptor; - while (outer->containing_type() != NULL) outer = outer->containing_type(); - - const string& outer_name = outer->full_name(); - string inner_name = descriptor->full_name().substr(outer_name.size()); - - if (qualified) { - return "::" + DotsToColons(outer_name) + DotsToUnderscores(inner_name); - } else { - return outer->name() + DotsToUnderscores(inner_name); +bool CanInitializeByZeroing(const FieldDescriptor* field) { + if (field->is_repeated() || field->is_extension()) return false; + switch (field->cpp_type()) { + case FieldDescriptor::CPPTYPE_ENUM: + return field->default_value_enum()->number() == 0; + case FieldDescriptor::CPPTYPE_INT32: + return field->default_value_int32() == 0; + case FieldDescriptor::CPPTYPE_INT64: + return field->default_value_int64() == 0; + case FieldDescriptor::CPPTYPE_UINT32: + return field->default_value_uint32() == 0; + case FieldDescriptor::CPPTYPE_UINT64: + return field->default_value_uint64() == 0; + case FieldDescriptor::CPPTYPE_FLOAT: + return field->default_value_float() == 0; + case FieldDescriptor::CPPTYPE_DOUBLE: + return field->default_value_double() == 0; + case FieldDescriptor::CPPTYPE_BOOL: + return field->default_value_bool() == false; + default: + return false; } } -string ClassName(const EnumDescriptor* enum_descriptor, bool qualified) { +string ClassName(const Descriptor* descriptor) { + const Descriptor* parent = descriptor->containing_type(); + string res; + if (parent) res += ClassName(parent) + "_"; + res += descriptor->name(); + if (IsMapEntryMessage(descriptor)) res += "_DoNotUse"; + return res; +} + +string ClassName(const EnumDescriptor* enum_descriptor) { if (enum_descriptor->containing_type() == NULL) { - if (qualified) { - return "::" + DotsToColons(enum_descriptor->full_name()); - } else { - return enum_descriptor->name(); - } + return enum_descriptor->name(); } else { - string result = ClassName(enum_descriptor->containing_type(), qualified); - result += '_'; - result += enum_descriptor->name(); - return result; + return ClassName(enum_descriptor->containing_type()) + "_" + + enum_descriptor->name(); } } +string Namespace(const string& package) { + if (package.empty()) return ""; + return "::" + DotsToColons(package); +} + string DefaultInstanceName(const Descriptor* descriptor) { string prefix = descriptor->file()->package().empty() ? "" : "::"; return prefix + DotsToColons(descriptor->file()->package()) + "::_" + ClassName(descriptor, false) + "_default_instance_"; } +string ReferenceFunctionName(const Descriptor* descriptor) { + return QualifiedClassName(descriptor) + "_Reference"; +} + string DependentBaseClassTemplateName(const Descriptor* descriptor) { return ClassName(descriptor, false) + "_InternalBase"; } @@ -210,6 +254,30 @@ string EnumValueName(const EnumValueDescriptor* enum_value) { return result; } +int EstimateAlignmentSize(const FieldDescriptor* field) { + if (field == NULL) return 0; + if (field->is_repeated()) return 8; + switch (field->cpp_type()) { + case FieldDescriptor::CPPTYPE_BOOL: + return 1; + + case FieldDescriptor::CPPTYPE_INT32: + case FieldDescriptor::CPPTYPE_UINT32: + case FieldDescriptor::CPPTYPE_ENUM: + case FieldDescriptor::CPPTYPE_FLOAT: + return 4; + + case FieldDescriptor::CPPTYPE_INT64: + case FieldDescriptor::CPPTYPE_UINT64: + case FieldDescriptor::CPPTYPE_DOUBLE: + case FieldDescriptor::CPPTYPE_STRING: + case FieldDescriptor::CPPTYPE_MESSAGE: + return 8; + } + GOOGLE_LOG(FATAL) << "Can't get here."; + return -1; // Make compiler happy. +} + string FieldConstantName(const FieldDescriptor *field) { string field_name = UnderscoresToCamelCase(field->name(), true); string result = "k" + field_name + "FieldNumber"; @@ -484,19 +552,6 @@ string SafeFunctionName(const Descriptor* descriptor, return function_name; } -bool StaticInitializersForced(const FileDescriptor* file, - const Options& options) { - if (HasDescriptorMethods(file, options) || file->extension_count() > 0) { - return true; - } - for (int i = 0; i < file->message_type_count(); ++i) { - if (HasExtension(file->message_type(i))) { - return true; - } - } - return false; -} - static bool HasMapFields(const Descriptor* descriptor) { for (int i = 0; i < descriptor->field_count(); ++i) { @@ -672,13 +727,11 @@ void Flatten(const Descriptor* descriptor, } // namespace -std::vector<const Descriptor*> FlattenMessagesInFile( - const FileDescriptor* file) { - std::vector<const Descriptor*> result; +void FlattenMessagesInFile(const FileDescriptor* file, + std::vector<const Descriptor*>* result) { for (int i = 0; i < file->message_type_count(); i++) { - Flatten(file->message_type(i), &result); + Flatten(file->message_type(i), result); } - return result; } bool HasWeakFields(const Descriptor* descriptor) { @@ -689,6 +742,27 @@ bool HasWeakFields(const FileDescriptor* file) { return false; } +bool UsingImplicitWeakFields(const FileDescriptor* file, + const Options& options) { + return options.lite_implicit_weak_fields && + GetOptimizeFor(file, options) == FileOptions::LITE_RUNTIME; +} + + +bool IsImplicitWeakField(const FieldDescriptor* field, const Options& options) { + return UsingImplicitWeakFields(field->file(), options) && + field->type() == FieldDescriptor::TYPE_MESSAGE && + !field->is_required() && !field->is_repeated() && !field->is_map() && + field->containing_oneof() == NULL && + field->message_type()->file() != field->file(); +} + +struct CompareDescriptors { + bool operator()(const Descriptor* a, const Descriptor* b) { + return a->full_name() < b->full_name(); + } +}; + SCCAnalyzer::NodeData SCCAnalyzer::DFS(const Descriptor* descriptor) { // Must not have visited already. GOOGLE_DCHECK_EQ(cache_.count(descriptor), 0); @@ -728,10 +802,33 @@ SCCAnalyzer::NodeData SCCAnalyzer::DFS(const Descriptor* descriptor) { if (scc_desc == descriptor) break; } + + // The order of descriptors is random and depends how this SCC was + // discovered. In-order to ensure maximum stability we sort it by name. + std::sort(scc->descriptors.begin(), scc->descriptors.end(), + CompareDescriptors()); + AddChildren(scc); } return result; } +void SCCAnalyzer::AddChildren(SCC* scc) { + std::set<const SCC*> seen; + for (int i = 0; i < scc->descriptors.size(); i++) { + const Descriptor* descriptor = scc->descriptors[i]; + for (int j = 0; j < descriptor->field_count(); j++) { + const Descriptor* child_msg = descriptor->field(j)->message_type(); + if (child_msg) { + const SCC* child = GetSCC(child_msg); + if (child == scc) continue; + if (seen.insert(child).second) { + scc->children.push_back(child); + } + } + } + } +} + MessageAnalysis SCCAnalyzer::GetSCCAnalysis(const SCC* scc) { if (analysis_cache_.count(scc)) return analysis_cache_[scc]; MessageAnalysis result = MessageAnalysis(); @@ -784,6 +881,46 @@ MessageAnalysis SCCAnalyzer::GetSCCAnalysis(const SCC* scc) { return analysis_cache_[scc] = result; } +void ListAllFields(const Descriptor* d, + std::vector<const FieldDescriptor*>* fields) { + // Collect sub messages + for (int i = 0; i < d->nested_type_count(); i++) { + ListAllFields(d->nested_type(i), fields); + } + // Collect message level extensions. + for (int i = 0; i < d->extension_count(); i++) { + fields->push_back(d->extension(i)); + } + // Add types of fields necessary + for (int i = 0; i < d->field_count(); i++) { + fields->push_back(d->field(i)); + } +} + +void ListAllFields(const FileDescriptor* d, + std::vector<const FieldDescriptor*>* fields) { + // Collect file level message. + for (int i = 0; i < d->message_type_count(); i++) { + ListAllFields(d->message_type(i), fields); + } + // Collect message level extensions. + for (int i = 0; i < d->extension_count(); i++) { + fields->push_back(d->extension(i)); + } +} + +void ListAllTypesForServices(const FileDescriptor* fd, + std::vector<const Descriptor*>* types) { + for (int i = 0; i < fd->service_count(); i++) { + const ServiceDescriptor* sd = fd->service(i); + for (int j = 0; j < sd->method_count(); j++) { + const MethodDescriptor* method = sd->method(j); + types->push_back(method->input_type()); + types->push_back(method->output_type()); + } + } +} + } // namespace cpp } // namespace compiler } // namespace protobuf |