Reorganize upb file structure This change moves almost everything in the `upb/` directory up one level, so that for example `upb/upb/generated_code_support.h` becomes just `upb/generated_code_support.h`. The only exceptions I made to this were that I left `upb/cmake` and `upb/BUILD` where they are, mostly because that avoids conflict with other files and the current locations seem reasonable for now. The `python/` directory is a little bit of a challenge because we had to merge the existing directory there with `upb/python/`. I made `upb/python/BUILD` into the BUILD file for the merged directory, and it effectively loads the contents of the other BUILD file via `python/build_targets.bzl`, but I plan to clean this up soon. PiperOrigin-RevId: 568651768
diff --git a/protos_generator/gen_utils.cc b/protos_generator/gen_utils.cc new file mode 100644 index 0000000..79dd5a1 --- /dev/null +++ b/protos_generator/gen_utils.cc
@@ -0,0 +1,152 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2023 Google LLC. 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 LLC 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 "protos_generator/gen_utils.h" + +#include <algorithm> +#include <string> +#include <vector> + +#include "absl/strings/ascii.h" + +namespace protos_generator { + +namespace protobuf = ::google::protobuf; + +void AddEnums(const protobuf::Descriptor* message, + std::vector<const protobuf::EnumDescriptor*>* enums) { + enums->reserve(enums->size() + message->enum_type_count()); + for (int i = 0; i < message->enum_type_count(); i++) { + enums->push_back(message->enum_type(i)); + } + for (int i = 0; i < message->nested_type_count(); i++) { + AddEnums(message->nested_type(i), enums); + } +} + +std::vector<const protobuf::EnumDescriptor*> SortedEnums( + const protobuf::FileDescriptor* file) { + std::vector<const protobuf::EnumDescriptor*> enums; + enums.reserve(file->enum_type_count()); + for (int i = 0; i < file->enum_type_count(); i++) { + enums.push_back(file->enum_type(i)); + } + for (int i = 0; i < file->message_type_count(); i++) { + AddEnums(file->message_type(i), &enums); + } + return enums; +} + +void AddMessages(const protobuf::Descriptor* message, + std::vector<const protobuf::Descriptor*>* messages) { + messages->push_back(message); + for (int i = 0; i < message->nested_type_count(); i++) { + AddMessages(message->nested_type(i), messages); + } +} + +std::vector<const protobuf::Descriptor*> SortedMessages( + const protobuf::FileDescriptor* file) { + std::vector<const protobuf::Descriptor*> messages; + for (int i = 0; i < file->message_type_count(); i++) { + AddMessages(file->message_type(i), &messages); + } + return messages; +} + +void AddExtensionsFromMessage( + const protobuf::Descriptor* message, + std::vector<const protobuf::FieldDescriptor*>* exts) { + for (int i = 0; i < message->extension_count(); i++) { + exts->push_back(message->extension(i)); + } + for (int i = 0; i < message->nested_type_count(); i++) { + AddExtensionsFromMessage(message->nested_type(i), exts); + } +} + +std::vector<const protobuf::FieldDescriptor*> SortedExtensions( + const protobuf::FileDescriptor* file) { + const int extension_count = file->extension_count(); + const int message_type_count = file->message_type_count(); + + std::vector<const protobuf::FieldDescriptor*> ret; + ret.reserve(extension_count + message_type_count); + + for (int i = 0; i < extension_count; i++) { + ret.push_back(file->extension(i)); + } + for (int i = 0; i < message_type_count; i++) { + AddExtensionsFromMessage(file->message_type(i), &ret); + } + + return ret; +} + +std::vector<const protobuf::FieldDescriptor*> FieldNumberOrder( + const protobuf::Descriptor* message) { + std::vector<const protobuf::FieldDescriptor*> fields; + fields.reserve(message->field_count()); + for (int i = 0; i < message->field_count(); i++) { + fields.push_back(message->field(i)); + } + std::sort(fields.begin(), fields.end(), + [](const protobuf::FieldDescriptor* a, + const protobuf::FieldDescriptor* b) { + return a->number() < b->number(); + }); + return fields; +} + +std::string ToCamelCase(const std::string& input, bool lower_first) { + bool capitalize_next = !lower_first; + std::string result; + result.reserve(input.size()); + + for (char character : input) { + if (character == '_') { + capitalize_next = true; + } else if (capitalize_next) { + result.push_back(absl::ascii_toupper(character)); + capitalize_next = false; + } else { + result.push_back(character); + } + } + + // Lower-case the first letter. + if (lower_first && !result.empty()) { + result[0] = absl::ascii_tolower(result[0]); + } + + return result; +} + +} // namespace protos_generator