• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 //     * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 //     * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 // Author: dweis@google.com (Daniel Weis)
32 //  Based on original Protocol Buffers design by
33 //  Sanjay Ghemawat, Jeff Dean, and others.
34 
35 #include <google/protobuf/compiler/java/java_message_builder_lite.h>
36 
37 #include <algorithm>
38 #include <google/protobuf/stubs/hash.h>
39 #include <map>
40 #include <memory>
41 #ifndef _SHARED_PTR_H
42 #include <google/protobuf/stubs/shared_ptr.h>
43 #endif
44 #include <vector>
45 
46 #include <google/protobuf/compiler/java/java_context.h>
47 #include <google/protobuf/compiler/java/java_doc_comment.h>
48 #include <google/protobuf/compiler/java/java_enum.h>
49 #include <google/protobuf/compiler/java/java_extension.h>
50 #include <google/protobuf/compiler/java/java_generator_factory.h>
51 #include <google/protobuf/compiler/java/java_helpers.h>
52 #include <google/protobuf/compiler/java/java_name_resolver.h>
53 #include <google/protobuf/io/coded_stream.h>
54 #include <google/protobuf/io/printer.h>
55 #include <google/protobuf/descriptor.pb.h>
56 #include <google/protobuf/wire_format.h>
57 #include <google/protobuf/stubs/strutil.h>
58 #include <google/protobuf/stubs/substitute.h>
59 
60 namespace google {
61 namespace protobuf {
62 namespace compiler {
63 namespace java {
64 
65 namespace {
GenerateHasBits(const Descriptor * descriptor)66 bool GenerateHasBits(const Descriptor* descriptor) {
67   return SupportFieldPresence(descriptor->file()) ||
68       HasRepeatedFields(descriptor);
69 }
70 
MapValueImmutableClassdName(const Descriptor * descriptor,ClassNameResolver * name_resolver)71 string MapValueImmutableClassdName(const Descriptor* descriptor,
72                                    ClassNameResolver* name_resolver) {
73   const FieldDescriptor* value_field = descriptor->FindFieldByName("value");
74   GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, value_field->type());
75   return name_resolver->GetImmutableClassName(value_field->message_type());
76 }
77 }  // namespace
78 
MessageBuilderLiteGenerator(const Descriptor * descriptor,Context * context)79 MessageBuilderLiteGenerator::MessageBuilderLiteGenerator(
80     const Descriptor* descriptor, Context* context)
81   : descriptor_(descriptor), context_(context),
82     name_resolver_(context->GetNameResolver()),
83     field_generators_(descriptor, context_) {
84   GOOGLE_CHECK(!HasDescriptorMethods(descriptor->file(), context->EnforceLite()))
85       << "Generator factory error: A lite message generator is used to "
86          "generate non-lite messages.";
87 }
88 
~MessageBuilderLiteGenerator()89 MessageBuilderLiteGenerator::~MessageBuilderLiteGenerator() {}
90 
91 void MessageBuilderLiteGenerator::
Generate(io::Printer * printer)92 Generate(io::Printer* printer) {
93   WriteMessageDocComment(printer, descriptor_);
94   printer->Print(
95     "public static final class Builder extends\n"
96     "    com.google.protobuf.GeneratedMessageLite.$extendible$Builder<\n"
97     "      $classname$, Builder> implements\n"
98     "    $extra_interfaces$\n"
99     "    $classname$OrBuilder {\n",
100     "classname", name_resolver_->GetImmutableClassName(descriptor_),
101     "extra_interfaces", ExtraBuilderInterfaces(descriptor_),
102     "extendible",
103     descriptor_->extension_range_count() > 0 ? "Extendable" : "");
104   printer->Indent();
105 
106   GenerateCommonBuilderMethods(printer);
107 
108   // oneof
109   map<string, string> vars;
110   for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
111     vars["oneof_name"] = context_->GetOneofGeneratorInfo(
112         descriptor_->oneof_decl(i))->name;
113     vars["oneof_capitalized_name"] = context_->GetOneofGeneratorInfo(
114         descriptor_->oneof_decl(i))->capitalized_name;
115     vars["oneof_index"] = SimpleItoa(descriptor_->oneof_decl(i)->index());
116 
117     // oneofCase() and clearOneof()
118     printer->Print(vars,
119       "public $oneof_capitalized_name$Case\n"
120       "    get$oneof_capitalized_name$Case() {\n"
121       "  return instance.get$oneof_capitalized_name$Case();\n"
122       "}\n"
123       "\n"
124       "public Builder clear$oneof_capitalized_name$() {\n"
125       "  copyOnWrite();\n"
126       "  instance.clear$oneof_capitalized_name$();\n"
127       "  return this;\n"
128       "}\n"
129       "\n");
130   }
131 
132   if (GenerateHasBits(descriptor_)) {
133     // Integers for bit fields.
134     int totalBits = 0;
135     for (int i = 0; i < descriptor_->field_count(); i++) {
136       totalBits += field_generators_.get(descriptor_->field(i))
137           .GetNumBitsForBuilder();
138     }
139     int totalInts = (totalBits + 31) / 32;
140     for (int i = 0; i < totalInts; i++) {
141       printer->Print("private int $bit_field_name$;\n",
142         "bit_field_name", GetBitFieldName(i));
143     }
144   }
145 
146   for (int i = 0; i < descriptor_->field_count(); i++) {
147     printer->Print("\n");
148     field_generators_.get(descriptor_->field(i))
149                      .GenerateBuilderMembers(printer);
150   }
151 
152   printer->Print(
153     "\n"
154     "// @@protoc_insertion_point(builder_scope:$full_name$)\n",
155     "full_name", descriptor_->full_name());
156 
157   printer->Outdent();
158   printer->Print("}\n");
159 }
160 
161 // ===================================================================
162 
163 void MessageBuilderLiteGenerator::
GenerateCommonBuilderMethods(io::Printer * printer)164 GenerateCommonBuilderMethods(io::Printer* printer) {
165   printer->Print(
166     "// Construct using $classname$.newBuilder()\n"
167     "private Builder() {\n"
168     "  super(DEFAULT_INSTANCE);\n"
169     "}\n"
170     "\n",
171     "classname", name_resolver_->GetImmutableClassName(descriptor_));
172 }
173 
174 // ===================================================================
175 
176 }  // namespace java
177 }  // namespace compiler
178 }  // namespace protobuf
179 }  // namespace google
180