From bf01e492732acc392bc3c4496788a3fdcfc85ab9 Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot Date: Thu, 12 Sep 2024 12:36:52 -0700 Subject: [PATCH] Moving Kotlin DSL file generator to its own directory PiperOrigin-RevId: 673960087 --- src/google/protobuf/compiler/java/file.cc | 75 --------- src/google/protobuf/compiler/java/file.h | 7 - .../protobuf/compiler/java/full/BUILD.bazel | 5 +- .../protobuf/compiler/java/lite/BUILD.bazel | 5 +- .../protobuf/compiler/kotlin/BUILD.bazel | 25 +++ src/google/protobuf/compiler/kotlin/file.cc | 142 ++++++++++++++++++ src/google/protobuf/compiler/kotlin/file.h | 79 ++++++++++ .../protobuf/compiler/kotlin/generator.cc | 24 +-- .../protobuf/compiler/kotlin/generator.h | 4 +- src/google/protobuf/compiler/main.cc | 2 +- 10 files changed, 269 insertions(+), 99 deletions(-) create mode 100644 src/google/protobuf/compiler/kotlin/file.cc create mode 100644 src/google/protobuf/compiler/kotlin/file.h diff --git a/src/google/protobuf/compiler/java/file.cc b/src/google/protobuf/compiler/java/file.cc index 6995513bd1..d59b0dcdc4 100644 --- a/src/google/protobuf/compiler/java/file.cc +++ b/src/google/protobuf/compiler/java/file.cc @@ -600,81 +600,6 @@ void FileGenerator::GenerateSiblings( } } -std::string FileGenerator::GetKotlinClassname() { - return name_resolver_->GetFileClassName(file_, immutable_api_, true); -} - -void FileGenerator::GenerateKotlin(io::Printer* printer) { - printer->Print( - "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" - "// NO CHECKED-IN PROTOBUF " - // Intentional line breaker - "GENCODE\n" - "// source: $filename$\n" - "\n", - "filename", file_->name()); - printer->Print( - "// Generated files should ignore deprecation warnings\n" - "@file:Suppress(\"DEPRECATION\")\n"); - if (!java_package_.empty()) { - printer->Print( - "package $package$;\n" - "\n", - "package", EscapeKotlinKeywords(java_package_)); - } -} - -void FileGenerator::GenerateKotlinSiblings( - const std::string& package_dir, GeneratorContext* context, - std::vector* file_list, - std::vector* annotation_list) { - for (int i = 0; i < file_->message_type_count(); i++) { - const Descriptor* descriptor = file_->message_type(i); - MessageGenerator* generator = message_generators_[i].get(); - auto open_file = [context](const std::string& filename) { - return std::unique_ptr(context->Open(filename)); - }; - std::string filename = - absl::StrCat(package_dir, descriptor->name(), "Kt.kt"); - file_list->push_back(filename); - std::string info_full_path = absl::StrCat(filename, ".pb.meta"); - GeneratedCodeInfo annotations; - io::AnnotationProtoCollector annotation_collector( - &annotations); - auto output = open_file(filename); - io::Printer printer( - output.get(), '$', - options_.annotate_code ? &annotation_collector : nullptr); - - printer.Print( - "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" - "// NO CHECKED-IN PROTOBUF " - // Intentional line breaker - "GENCODE\n" - "// source: $filename$\n" - "\n", - "filename", descriptor->file()->name()); - printer.Print( - "// Generated files should ignore deprecation warnings\n" - "@file:Suppress(\"DEPRECATION\")\n"); - if (!java_package_.empty()) { - printer.Print( - "package $package$;\n" - "\n", - "package", EscapeKotlinKeywords(java_package_)); - } - - generator->GenerateKotlinMembers(&printer); - generator->GenerateTopLevelKotlinMembers(&printer); - - if (options_.annotate_code) { - auto info_output = open_file(info_full_path); - annotations.SerializeToZeroCopyStream(info_output.get()); - annotation_list->push_back(info_full_path); - } - } -} - bool FileGenerator::ShouldIncludeDependency(const FileDescriptor* descriptor, bool immutable_api) { // Skip feature imports, which are a visible (but non-functional) deviation diff --git a/src/google/protobuf/compiler/java/file.h b/src/google/protobuf/compiler/java/file.h index 7d995ee33c..f610befc2c 100644 --- a/src/google/protobuf/compiler/java/file.h +++ b/src/google/protobuf/compiler/java/file.h @@ -58,13 +58,6 @@ class FileGenerator { void Generate(io::Printer* printer); - std::string GetKotlinClassname(); - void GenerateKotlin(io::Printer* printer); - void GenerateKotlinSiblings(const std::string& package_dir, - GeneratorContext* generator_context, - std::vector* file_list, - std::vector* annotation_list); - // If we aren't putting everything into one file, this will write all the // files other than the outer file (i.e. one for each message, enum, and // service type). diff --git a/src/google/protobuf/compiler/java/full/BUILD.bazel b/src/google/protobuf/compiler/java/full/BUILD.bazel index c708696321..bee46663d4 100644 --- a/src/google/protobuf/compiler/java/full/BUILD.bazel +++ b/src/google/protobuf/compiler/java/full/BUILD.bazel @@ -112,7 +112,10 @@ cc_library( "message_builder.h", ], strip_include_prefix = "/src", - visibility = ["//src/google/protobuf/compiler/java:__pkg__"], + visibility = [ + "//src/google/protobuf/compiler/java:__pkg__", + "//src/google/protobuf/compiler/kotlin:__pkg__", + ], deps = [ ":eg", ":fg", diff --git a/src/google/protobuf/compiler/java/lite/BUILD.bazel b/src/google/protobuf/compiler/java/lite/BUILD.bazel index ec4b222aa6..8171f5af14 100644 --- a/src/google/protobuf/compiler/java/lite/BUILD.bazel +++ b/src/google/protobuf/compiler/java/lite/BUILD.bazel @@ -60,7 +60,10 @@ cc_library( "message_builder.h", ], strip_include_prefix = "/src", - visibility = ["//src/google/protobuf/compiler/java:__subpackages__"], + visibility = [ + "//src/google/protobuf/compiler/java:__subpackages__", + "//src/google/protobuf/compiler/kotlin:__subpackages__", + ], deps = [ ":field_generators", "//src/google/protobuf", diff --git a/src/google/protobuf/compiler/kotlin/BUILD.bazel b/src/google/protobuf/compiler/kotlin/BUILD.bazel index 82d88a0fbf..2b361e7bb6 100644 --- a/src/google/protobuf/compiler/kotlin/BUILD.bazel +++ b/src/google/protobuf/compiler/kotlin/BUILD.bazel @@ -8,6 +8,7 @@ cc_library( "//src/google/protobuf/compiler:__pkg__", ], deps = [ + ":kotlin_internal", "//src/google/protobuf", "//src/google/protobuf:port", "//src/google/protobuf/compiler:code_generator", @@ -17,3 +18,27 @@ cc_library( "@com_google_absl//absl/strings", ], ) + +cc_library( + name = "kotlin_internal", + srcs = ["file.cc"], + hdrs = ["file.h"], + strip_include_prefix = "/src", + visibility = [ + "//pkg:__pkg__", + "//src/google/protobuf/compiler:__pkg__", + ], + deps = [ + "//src/google/protobuf", + "//src/google/protobuf:port", + "//src/google/protobuf:protobuf_lite", + "//src/google/protobuf/compiler:code_generator", + "//src/google/protobuf/compiler/java", + "//src/google/protobuf/compiler/java:helpers", + "//src/google/protobuf/compiler/java/full", + "//src/google/protobuf/compiler/java/lite", + "//src/google/protobuf/io", + "//src/google/protobuf/io:printer", + "@com_google_absl//absl/strings", + ], +) diff --git a/src/google/protobuf/compiler/kotlin/file.cc b/src/google/protobuf/compiler/kotlin/file.cc new file mode 100644 index 0000000000..6d586a8c11 --- /dev/null +++ b/src/google/protobuf/compiler/kotlin/file.cc @@ -0,0 +1,142 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +// Generates Kotlin code for a given .proto file. + +#include "google/protobuf/compiler/kotlin/file.h" + +#include +#include +#include + +#include "absl/strings/str_cat.h" +#include "google/protobuf/compiler/code_generator.h" +#include "google/protobuf/compiler/java/context.h" +#include "google/protobuf/compiler/java/generator_factory.h" +#include "google/protobuf/compiler/java/helpers.h" +#include "google/protobuf/compiler/java/full/generator_factory.h" +#include "google/protobuf/compiler/java/lite/generator_factory.h" +#include "google/protobuf/compiler/java/name_resolver.h" +#include "google/protobuf/compiler/java/names.h" +#include "google/protobuf/compiler/java/options.h" +#include "google/protobuf/descriptor.pb.h" +#include "google/protobuf/io/printer.h" + +namespace google { +namespace protobuf { +namespace compiler { +namespace kotlin { + +using google::protobuf::compiler::java::Context; +using google::protobuf::compiler::java::Options; + +// class LiteGeneratorFactory; + +namespace { +std::unique_ptr CreateGeneratorFactory( + const FileDescriptor* file, const Options& options, Context* context) { + if (java::HasDescriptorMethods(file, context->EnforceLite())) { + return java::MakeImmutableGeneratorFactory(context); + } else { + return java::MakeImmutableLiteGeneratorFactory(context); + } +} +} // namespace + +FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options) + : file_(file), + java_package_(java::FileJavaPackage(file, options)), + message_generators_(file->message_type_count()), + context_(new Context(file, options)), + generator_factory_(CreateGeneratorFactory(file, options, context_.get())), + name_resolver_(context_->GetNameResolver()), + options_(options) { + for (int i = 0; i < file_->message_type_count(); ++i) { + message_generators_[i] = + generator_factory_->NewMessageGenerator(file_->message_type(i)); + } +} + +std::string FileGenerator::GetKotlinClassname() { + return absl::StrCat(name_resolver_->GetFileImmutableClassName(file_), "Kt"); +} + +void FileGenerator::Generate(io::Printer* printer) { + printer->Print( + "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" + "// NO CHECKED-IN PROTOBUF " + // Intentional line breaker + "GENCODE\n" + "// source: $filename$\n" + "\n", + "filename", file_->name()); + printer->Print( + "// Generated files should ignore deprecation warnings\n" + "@file:Suppress(\"DEPRECATION\")\n"); + if (!java_package_.empty()) { + printer->Print( + "package $package$;\n" + "\n", + "package", java::EscapeKotlinKeywords(java_package_)); + } +} + +void FileGenerator::GenerateSiblings( + const std::string& package_dir, GeneratorContext* context, + std::vector* file_list, + std::vector* annotation_list) { + for (int i = 0; i < file_->message_type_count(); i++) { + const Descriptor* descriptor = file_->message_type(i); + java::MessageGenerator* generator = message_generators_[i].get(); + auto open_file = [context](const std::string& filename) { + return std::unique_ptr(context->Open(filename)); + }; + std::string filename = + absl::StrCat(package_dir, descriptor->name(), "Kt.kt"); + file_list->push_back(filename); + std::string info_full_path = absl::StrCat(filename, ".pb.meta"); + GeneratedCodeInfo annotations; + io::AnnotationProtoCollector annotation_collector( + &annotations); + auto output = open_file(filename); + io::Printer printer( + output.get(), '$', + options_.annotate_code ? &annotation_collector : nullptr); + + printer.Print( + "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" + "// NO CHECKED-IN PROTOBUF " + // Intentional line breaker + "GENCODE\n" + "// source: $filename$\n" + "\n", + "filename", descriptor->file()->name()); + printer.Print( + "// Generated files should ignore deprecation warnings\n" + "@file:Suppress(\"DEPRECATION\")\n"); + if (!java_package_.empty()) { + printer.Print( + "package $package$;\n" + "\n", + "package", java::EscapeKotlinKeywords(java_package_)); + } + + generator->GenerateKotlinMembers(&printer); + generator->GenerateTopLevelKotlinMembers(&printer); + + if (options_.annotate_code) { + auto info_output = open_file(info_full_path); + annotations.SerializeToZeroCopyStream(info_output.get()); + annotation_list->push_back(info_full_path); + } + } +} + +} // namespace kotlin +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/compiler/kotlin/file.h b/src/google/protobuf/compiler/kotlin/file.h new file mode 100644 index 0000000000..4c5fbf76ae --- /dev/null +++ b/src/google/protobuf/compiler/kotlin/file.h @@ -0,0 +1,79 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file or at +// https://developers.google.com/open-source/licenses/bsd + +// Generates Kotlin code for a given .proto file. + +#ifndef GOOGLE_PROTOBUF_COMPILER_KOTLIN_FILE_H__ +#define GOOGLE_PROTOBUF_COMPILER_KOTLIN_FILE_H__ + +#include +#include +#include + +#include "google/protobuf/compiler/java/generator_factory.h" +#include "google/protobuf/compiler/java/options.h" + +namespace google { +namespace protobuf { +class FileDescriptor; // descriptor.h +namespace io { +class Printer; // printer.h +} +namespace compiler { +class GeneratorContext; // code_generator.h +namespace java { +class Context; // context.h +class MessageGenerator; // message.h +class GeneratorFactory; // generator_factory.h +class ExtensionGenerator; // extension.h +class ClassNameResolver; // name_resolver.h +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +namespace google { +namespace protobuf { +namespace compiler { +namespace kotlin { + +// TODO: b/366047913 - Move away from these generator classes and more towards +// the "Context" model that the Kotlin Native & Rust code generators use: +// http://google3/third_party/kotlin/protobuf/generator/native/file.cc;l=149-170;rcl=642292300 +class FileGenerator { + public: + FileGenerator(const FileDescriptor* file, const java::Options& options); + FileGenerator(const FileGenerator&) = delete; + FileGenerator& operator=(const FileGenerator&) = delete; + ~FileGenerator() = default; + + std::string GetKotlinClassname(); + void Generate(io::Printer* printer); + void GenerateSiblings(const std::string& package_dir, + GeneratorContext* generator_context, + std::vector* file_list, + std::vector* annotation_list); + + const std::string& java_package() { return java_package_; } + + private: + const FileDescriptor* file_; + std::string java_package_; + + std::vector> message_generators_; + std::unique_ptr context_; + std::unique_ptr generator_factory_; + java::ClassNameResolver* name_resolver_; + const java::Options options_; +}; + +} // namespace kotlin +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_KOTLIN_FILE_H__ diff --git a/src/google/protobuf/compiler/kotlin/generator.cc b/src/google/protobuf/compiler/kotlin/generator.cc index 54c2018b27..da2ee921f6 100644 --- a/src/google/protobuf/compiler/kotlin/generator.cc +++ b/src/google/protobuf/compiler/kotlin/generator.cc @@ -15,15 +15,17 @@ #include "absl/strings/str_cat.h" #include "google/protobuf/compiler/code_generator.h" -#include "google/protobuf/compiler/java/file.h" #include "google/protobuf/compiler/java/helpers.h" #include "google/protobuf/compiler/java/options.h" +#include "google/protobuf/compiler/kotlin/file.h" #include "google/protobuf/io/printer.h" namespace google { namespace protobuf { namespace compiler { -namespace java { +namespace kotlin { + +using google::protobuf::compiler::java::Options; KotlinGenerator::KotlinGenerator() {} KotlinGenerator::~KotlinGenerator() {} @@ -80,16 +82,15 @@ bool KotlinGenerator::Generate(const FileDescriptor* file, std::vector all_annotations; std::unique_ptr file_generator( - new FileGenerator(file, file_options, /* immutable_api = */ true)); + new FileGenerator(file, file_options)); - if (!file_generator || !file_generator->Validate(error)) { - return false; - } + if (!file_generator) return false; auto open_file = [context](const std::string& filename) { return std::unique_ptr(context->Open(filename)); }; - std::string package_dir = JavaPackageToDir(file_generator->java_package()); + std::string package_dir = + java::JavaPackageToDir(file_generator->java_package()); std::string kotlin_filename = absl::StrCat( package_dir, file_generator->GetKotlinClassname(), ".proto.kt"); all_files.push_back(kotlin_filename); @@ -107,10 +108,9 @@ bool KotlinGenerator::Generate(const FileDescriptor* file, output.get(), '$', file_options.annotate_code ? &annotation_collector : nullptr); - file_generator->GenerateKotlin(&printer); - - file_generator->GenerateKotlinSiblings(package_dir, context, &all_files, - &all_annotations); + file_generator->Generate(&printer); + file_generator->GenerateSiblings(package_dir, context, &all_files, + &all_annotations); if (file_options.annotate_code) { auto info_output = open_file(info_full_path); @@ -142,7 +142,7 @@ bool KotlinGenerator::Generate(const FileDescriptor* file, return true; } -} // namespace java +} // namespace kotlin } // namespace compiler } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/compiler/kotlin/generator.h b/src/google/protobuf/compiler/kotlin/generator.h index cb8df6cfca..5e57659ada 100644 --- a/src/google/protobuf/compiler/kotlin/generator.h +++ b/src/google/protobuf/compiler/kotlin/generator.h @@ -24,7 +24,7 @@ namespace google { namespace protobuf { namespace compiler { -namespace java { +namespace kotlin { // CodeGenerator implementation which generates Kotlin code. If you create your // own protocol compiler binary and you want it to support Kotlin output, you @@ -53,7 +53,7 @@ class PROTOC_EXPORT KotlinGenerator : public CodeGenerator { using CodeGenerator::GetResolvedSourceFeatures; }; -} // namespace java +} // namespace kotlin } // namespace compiler } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/compiler/main.cc b/src/google/protobuf/compiler/main.cc index f634e0cdc1..babede8faa 100644 --- a/src/google/protobuf/compiler/main.cc +++ b/src/google/protobuf/compiler/main.cc @@ -63,7 +63,7 @@ int ProtobufMain(int argc, char* argv[]) { #endif // Proto2 Kotlin - java::KotlinGenerator kt_generator; + kotlin::KotlinGenerator kt_generator; cli.RegisterGenerator("--kotlin_out", "--kotlin_opt", &kt_generator, "Generate Kotlin file.");