Skip to content

Commit

Permalink
Moving Kotlin DSL file generator to its own directory
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 673960087
  • Loading branch information
protobuf-github-bot authored and copybara-github committed Sep 12, 2024
1 parent 9d835e6 commit bf01e49
Show file tree
Hide file tree
Showing 10 changed files with 269 additions and 99 deletions.
75 changes: 0 additions & 75 deletions src/google/protobuf/compiler/java/file.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::string>* file_list,
std::vector<std::string>* 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<io::ZeroCopyOutputStream>(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<GeneratedCodeInfo> 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
Expand Down
7 changes: 0 additions & 7 deletions src/google/protobuf/compiler/java/file.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::string>* file_list,
std::vector<std::string>* 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).
Expand Down
5 changes: 4 additions & 1 deletion src/google/protobuf/compiler/java/full/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
5 changes: 4 additions & 1 deletion src/google/protobuf/compiler/java/lite/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
25 changes: 25 additions & 0 deletions src/google/protobuf/compiler/kotlin/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
],
)
142 changes: 142 additions & 0 deletions src/google/protobuf/compiler/kotlin/file.cc
Original file line number Diff line number Diff line change
@@ -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 <memory>
#include <string>
#include <vector>

#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<java::GeneratorFactory> 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<std::string>* file_list,
std::vector<std::string>* 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<io::ZeroCopyOutputStream>(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<GeneratedCodeInfo> 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
79 changes: 79 additions & 0 deletions src/google/protobuf/compiler/kotlin/file.h
Original file line number Diff line number Diff line change
@@ -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 <memory>
#include <string>
#include <vector>

#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<std::string>* file_list,
std::vector<std::string>* annotation_list);

const std::string& java_package() { return java_package_; }

private:
const FileDescriptor* file_;
std::string java_package_;

std::vector<std::unique_ptr<java::MessageGenerator>> message_generators_;
std::unique_ptr<java::Context> context_;
std::unique_ptr<java::GeneratorFactory> 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__
Loading

0 comments on commit bf01e49

Please sign in to comment.