1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7
8 // Author: dweis@google.com (Daniel Weis)
9 // Based on original Protocol Buffers design by
10 // Sanjay Ghemawat, Jeff Dean, and others.
11
12 #include "google/protobuf/compiler/java/lite/message_builder.h"
13
14 #include <string>
15
16 #include "absl/container/flat_hash_map.h"
17 #include "absl/strings/str_cat.h"
18 #include "google/protobuf/compiler/java/context.h"
19 #include "google/protobuf/compiler/java/doc_comment.h"
20 #include "google/protobuf/compiler/java/field_common.h"
21 #include "google/protobuf/compiler/java/helpers.h"
22 #include "google/protobuf/compiler/java/lite/enum.h"
23 #include "google/protobuf/compiler/java/lite/make_field_gens.h"
24 #include "google/protobuf/compiler/java/name_resolver.h"
25 #include "google/protobuf/descriptor.pb.h"
26 #include "google/protobuf/io/printer.h"
27
28 // Must be last.
29 #include "google/protobuf/port_def.inc"
30
31 namespace google {
32 namespace protobuf {
33 namespace compiler {
34 namespace java {
35
MessageBuilderLiteGenerator(const Descriptor * descriptor,Context * context)36 MessageBuilderLiteGenerator::MessageBuilderLiteGenerator(
37 const Descriptor* descriptor, Context* context)
38 : descriptor_(descriptor),
39 context_(context),
40 name_resolver_(context->GetNameResolver()),
41 field_generators_(MakeImmutableFieldLiteGenerators(descriptor, context)) {
42 ABSL_CHECK(!HasDescriptorMethods(descriptor->file(), context->EnforceLite()))
43 << "Generator factory error: A lite message generator is used to "
44 "generate non-lite messages.";
45 for (int i = 0; i < descriptor_->field_count(); i++) {
46 if (IsRealOneof(descriptor_->field(i))) {
47 const OneofDescriptor* oneof = descriptor_->field(i)->containing_oneof();
48 ABSL_CHECK(oneofs_.emplace(oneof->index(), oneof).first->second == oneof);
49 }
50 }
51 }
52
~MessageBuilderLiteGenerator()53 MessageBuilderLiteGenerator::~MessageBuilderLiteGenerator() {}
54
Generate(io::Printer * printer)55 void MessageBuilderLiteGenerator::Generate(io::Printer* printer) {
56 WriteMessageDocComment(printer, descriptor_, context_->options());
57 absl::flat_hash_map<absl::string_view, std::string> vars = {
58 {"{", ""},
59 {"}", ""},
60 {"classname", name_resolver_->GetImmutableClassName(descriptor_)},
61 {"extra_interfaces", ExtraBuilderInterfaces(descriptor_)},
62 {"extendible",
63 descriptor_->extension_range_count() > 0 ? "Extendable" : ""},
64 };
65 printer->Print(
66 vars,
67 "public static final class ${$Builder$}$ extends\n"
68 " com.google.protobuf.GeneratedMessageLite.$extendible$Builder<\n"
69 " $classname$, Builder> implements\n"
70 " $extra_interfaces$\n"
71 " $classname$OrBuilder {\n");
72 printer->Annotate("{", "}", descriptor_);
73 printer->Indent();
74
75 GenerateCommonBuilderMethods(printer);
76
77 // oneof
78 for (auto& kv : oneofs_) {
79 const OneofDescriptor* oneof = kv.second;
80 vars["oneof_name"] = context_->GetOneofGeneratorInfo(oneof)->name;
81 vars["oneof_capitalized_name"] =
82 context_->GetOneofGeneratorInfo(oneof)->capitalized_name;
83 vars["oneof_index"] = absl::StrCat(oneof->index());
84
85 // oneofCase() and clearOneof()
86 printer->Print(vars,
87 "@java.lang.Override\n"
88 "public $oneof_capitalized_name$Case\n"
89 " ${$get$oneof_capitalized_name$Case$}$() {\n"
90 " return instance.get$oneof_capitalized_name$Case();\n"
91 "}\n");
92 printer->Annotate("{", "}", oneof);
93 printer->Print(vars,
94 "\n"
95 "public Builder ${$clear$oneof_capitalized_name$$}$() {\n"
96 " copyOnWrite();\n"
97 " instance.clear$oneof_capitalized_name$();\n"
98 " return this;\n"
99 "}\n"
100 "\n");
101 printer->Annotate("{", "}", oneof);
102 }
103
104 for (int i = 0; i < descriptor_->field_count(); i++) {
105 printer->Print("\n");
106 field_generators_.get(descriptor_->field(i))
107 .GenerateBuilderMembers(printer);
108 }
109
110 printer->Print(
111 "\n"
112 "// @@protoc_insertion_point(builder_scope:$full_name$)\n",
113 "full_name", descriptor_->full_name());
114
115 printer->Outdent();
116 printer->Print("}\n");
117 }
118
119 // ===================================================================
120
GenerateCommonBuilderMethods(io::Printer * printer)121 void MessageBuilderLiteGenerator::GenerateCommonBuilderMethods(
122 io::Printer* printer) {
123 printer->Print(
124 "// Construct using $classname$.newBuilder()\n"
125 "private Builder() {\n"
126 " super(DEFAULT_INSTANCE);\n"
127 "}\n"
128 "\n",
129 "classname", name_resolver_->GetImmutableClassName(descriptor_));
130 }
131
132 // ===================================================================
133
134 } // namespace java
135 } // namespace compiler
136 } // namespace protobuf
137 } // namespace google
138
139 #include "google/protobuf/port_undef.inc"
140