• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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