• 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: kenton@google.com (Kenton Varda)
32 //  Based on original Protocol Buffers design by
33 //  Sanjay Ghemawat, Jeff Dean, and others.
34 
35 #include <google/protobuf/compiler/java/java_field.h>
36 
37 #include <memory>
38 
39 #include <google/protobuf/stubs/logging.h>
40 #include <google/protobuf/stubs/common.h>
41 #include <google/protobuf/compiler/java/java_context.h>
42 #include <google/protobuf/compiler/java/java_enum_field.h>
43 #include <google/protobuf/compiler/java/java_enum_field_lite.h>
44 #include <google/protobuf/compiler/java/java_helpers.h>
45 #include <google/protobuf/compiler/java/java_map_field.h>
46 #include <google/protobuf/compiler/java/java_map_field_lite.h>
47 #include <google/protobuf/compiler/java/java_message_field.h>
48 #include <google/protobuf/compiler/java/java_message_field_lite.h>
49 #include <google/protobuf/compiler/java/java_primitive_field.h>
50 #include <google/protobuf/compiler/java/java_primitive_field_lite.h>
51 #include <google/protobuf/compiler/java/java_string_field.h>
52 #include <google/protobuf/compiler/java/java_string_field_lite.h>
53 #include <google/protobuf/io/printer.h>
54 #include <google/protobuf/stubs/strutil.h>
55 #include <google/protobuf/stubs/substitute.h>
56 
57 
58 namespace google {
59 namespace protobuf {
60 namespace compiler {
61 namespace java {
62 
63 namespace {
64 
MakeImmutableGenerator(const FieldDescriptor * field,int messageBitIndex,int builderBitIndex,Context * context)65 ImmutableFieldGenerator* MakeImmutableGenerator(const FieldDescriptor* field,
66                                                 int messageBitIndex,
67                                                 int builderBitIndex,
68                                                 Context* context) {
69   if (field->is_repeated()) {
70     switch (GetJavaType(field)) {
71       case JAVATYPE_MESSAGE:
72         if (IsMapEntry(field->message_type())) {
73           return new ImmutableMapFieldGenerator(field, messageBitIndex,
74                                                 builderBitIndex, context);
75         } else {
76           return new RepeatedImmutableMessageFieldGenerator(
77               field, messageBitIndex, builderBitIndex, context);
78         }
79       case JAVATYPE_ENUM:
80         return new RepeatedImmutableEnumFieldGenerator(
81             field, messageBitIndex, builderBitIndex, context);
82       case JAVATYPE_STRING:
83         return new RepeatedImmutableStringFieldGenerator(
84             field, messageBitIndex, builderBitIndex, context);
85       default:
86         return new RepeatedImmutablePrimitiveFieldGenerator(
87             field, messageBitIndex, builderBitIndex, context);
88     }
89   } else {
90     if (IsRealOneof(field)) {
91       switch (GetJavaType(field)) {
92         case JAVATYPE_MESSAGE:
93           return new ImmutableMessageOneofFieldGenerator(
94               field, messageBitIndex, builderBitIndex, context);
95         case JAVATYPE_ENUM:
96           return new ImmutableEnumOneofFieldGenerator(field, messageBitIndex,
97                                                       builderBitIndex, context);
98         case JAVATYPE_STRING:
99           return new ImmutableStringOneofFieldGenerator(
100               field, messageBitIndex, builderBitIndex, context);
101         default:
102           return new ImmutablePrimitiveOneofFieldGenerator(
103               field, messageBitIndex, builderBitIndex, context);
104       }
105     } else {
106       switch (GetJavaType(field)) {
107         case JAVATYPE_MESSAGE:
108           return new ImmutableMessageFieldGenerator(field, messageBitIndex,
109                                                     builderBitIndex, context);
110         case JAVATYPE_ENUM:
111           return new ImmutableEnumFieldGenerator(field, messageBitIndex,
112                                                  builderBitIndex, context);
113         case JAVATYPE_STRING:
114           return new ImmutableStringFieldGenerator(field, messageBitIndex,
115                                                    builderBitIndex, context);
116         default:
117           return new ImmutablePrimitiveFieldGenerator(field, messageBitIndex,
118                                                       builderBitIndex, context);
119       }
120     }
121   }
122 }
123 
MakeImmutableLiteGenerator(const FieldDescriptor * field,int messageBitIndex,Context * context)124 ImmutableFieldLiteGenerator* MakeImmutableLiteGenerator(
125     const FieldDescriptor* field, int messageBitIndex, Context* context) {
126   if (field->is_repeated()) {
127     switch (GetJavaType(field)) {
128       case JAVATYPE_MESSAGE:
129         if (IsMapEntry(field->message_type())) {
130           return new ImmutableMapFieldLiteGenerator(field, messageBitIndex,
131                                                     context);
132         } else {
133           return new RepeatedImmutableMessageFieldLiteGenerator(
134               field, messageBitIndex, context);
135         }
136       case JAVATYPE_ENUM:
137         return new RepeatedImmutableEnumFieldLiteGenerator(
138             field, messageBitIndex, context);
139       case JAVATYPE_STRING:
140         return new RepeatedImmutableStringFieldLiteGenerator(
141             field, messageBitIndex, context);
142       default:
143         return new RepeatedImmutablePrimitiveFieldLiteGenerator(
144             field, messageBitIndex, context);
145     }
146   } else {
147     if (IsRealOneof(field)) {
148       switch (GetJavaType(field)) {
149         case JAVATYPE_MESSAGE:
150           return new ImmutableMessageOneofFieldLiteGenerator(
151               field, messageBitIndex, context);
152         case JAVATYPE_ENUM:
153           return new ImmutableEnumOneofFieldLiteGenerator(
154               field, messageBitIndex, context);
155         case JAVATYPE_STRING:
156           return new ImmutableStringOneofFieldLiteGenerator(
157               field, messageBitIndex, context);
158         default:
159           return new ImmutablePrimitiveOneofFieldLiteGenerator(
160               field, messageBitIndex, context);
161       }
162     } else {
163       switch (GetJavaType(field)) {
164         case JAVATYPE_MESSAGE:
165           return new ImmutableMessageFieldLiteGenerator(field, messageBitIndex,
166                                                         context);
167         case JAVATYPE_ENUM:
168           return new ImmutableEnumFieldLiteGenerator(field, messageBitIndex,
169                                                      context);
170         case JAVATYPE_STRING:
171           return new ImmutableStringFieldLiteGenerator(field, messageBitIndex,
172                                                        context);
173         default:
174           return new ImmutablePrimitiveFieldLiteGenerator(
175               field, messageBitIndex, context);
176       }
177     }
178   }
179 }
180 
181 
ReportUnexpectedPackedFieldsCall(io::Printer * printer)182 static inline void ReportUnexpectedPackedFieldsCall(io::Printer* printer) {
183   // Reaching here indicates a bug. Cases are:
184   //   - This FieldGenerator should support packing,
185   //     but this method should be overridden.
186   //   - This FieldGenerator doesn't support packing, and this method
187   //     should never have been called.
188   GOOGLE_LOG(FATAL) << "GenerateParsingCodeFromPacked() "
189              << "called on field generator that does not support packing.";
190 }
191 
192 }  // namespace
193 
~ImmutableFieldGenerator()194 ImmutableFieldGenerator::~ImmutableFieldGenerator() {}
195 
GenerateParsingCodeFromPacked(io::Printer * printer) const196 void ImmutableFieldGenerator::GenerateParsingCodeFromPacked(
197     io::Printer* printer) const {
198   ReportUnexpectedPackedFieldsCall(printer);
199 }
200 
~ImmutableFieldLiteGenerator()201 ImmutableFieldLiteGenerator::~ImmutableFieldLiteGenerator() {}
202 
203 // ===================================================================
204 
205 template <>
FieldGeneratorMap(const Descriptor * descriptor,Context * context)206 FieldGeneratorMap<ImmutableFieldGenerator>::FieldGeneratorMap(
207     const Descriptor* descriptor, Context* context)
208     : descriptor_(descriptor), field_generators_(descriptor->field_count()) {
209   // Construct all the FieldGenerators and assign them bit indices for their
210   // bit fields.
211   int messageBitIndex = 0;
212   int builderBitIndex = 0;
213   for (int i = 0; i < descriptor->field_count(); i++) {
214     ImmutableFieldGenerator* generator = MakeImmutableGenerator(
215         descriptor->field(i), messageBitIndex, builderBitIndex, context);
216     field_generators_[i].reset(generator);
217     messageBitIndex += generator->GetNumBitsForMessage();
218     builderBitIndex += generator->GetNumBitsForBuilder();
219   }
220 }
221 
222 template <>
~FieldGeneratorMap()223 FieldGeneratorMap<ImmutableFieldGenerator>::~FieldGeneratorMap() {}
224 
225 template <>
FieldGeneratorMap(const Descriptor * descriptor,Context * context)226 FieldGeneratorMap<ImmutableFieldLiteGenerator>::FieldGeneratorMap(
227     const Descriptor* descriptor, Context* context)
228     : descriptor_(descriptor), field_generators_(descriptor->field_count()) {
229   // Construct all the FieldGenerators and assign them bit indices for their
230   // bit fields.
231   int messageBitIndex = 0;
232   for (int i = 0; i < descriptor->field_count(); i++) {
233     ImmutableFieldLiteGenerator* generator = MakeImmutableLiteGenerator(
234         descriptor->field(i), messageBitIndex, context);
235     field_generators_[i].reset(generator);
236     messageBitIndex += generator->GetNumBitsForMessage();
237   }
238 }
239 
240 template <>
~FieldGeneratorMap()241 FieldGeneratorMap<ImmutableFieldLiteGenerator>::~FieldGeneratorMap() {}
242 
243 
SetCommonFieldVariables(const FieldDescriptor * descriptor,const FieldGeneratorInfo * info,std::map<std::string,std::string> * variables)244 void SetCommonFieldVariables(const FieldDescriptor* descriptor,
245                              const FieldGeneratorInfo* info,
246                              std::map<std::string, std::string>* variables) {
247   (*variables)["field_name"] = descriptor->name();
248   (*variables)["name"] = info->name;
249   (*variables)["classname"] = descriptor->containing_type()->name();
250   (*variables)["capitalized_name"] = info->capitalized_name;
251   (*variables)["disambiguated_reason"] = info->disambiguated_reason;
252   (*variables)["constant_name"] = FieldConstantName(descriptor);
253   (*variables)["number"] = StrCat(descriptor->number());
254   (*variables)["kt_dsl_builder"] = "_builder";
255   // These variables are placeholders to pick out the beginning and ends of
256   // identifiers for annotations (when doing so with existing variables would
257   // be ambiguous or impossible). They should never be set to anything but the
258   // empty string.
259   (*variables)["{"] = "";
260   (*variables)["}"] = "";
261 }
262 
SetCommonOneofVariables(const FieldDescriptor * descriptor,const OneofGeneratorInfo * info,std::map<std::string,std::string> * variables)263 void SetCommonOneofVariables(const FieldDescriptor* descriptor,
264                              const OneofGeneratorInfo* info,
265                              std::map<std::string, std::string>* variables) {
266   (*variables)["oneof_name"] = info->name;
267   (*variables)["oneof_capitalized_name"] = info->capitalized_name;
268   (*variables)["oneof_index"] =
269       StrCat(descriptor->containing_oneof()->index());
270   (*variables)["oneof_stored_type"] = GetOneofStoredType(descriptor);
271   (*variables)["set_oneof_case_message"] =
272       info->name + "Case_ = " + StrCat(descriptor->number());
273   (*variables)["clear_oneof_case_message"] = info->name + "Case_ = 0";
274   (*variables)["has_oneof_case_message"] =
275       info->name + "Case_ == " + StrCat(descriptor->number());
276 }
277 
PrintExtraFieldInfo(const std::map<std::string,std::string> & variables,io::Printer * printer)278 void PrintExtraFieldInfo(const std::map<std::string, std::string>& variables,
279                          io::Printer* printer) {
280   const std::map<std::string, std::string>::const_iterator it =
281       variables.find("disambiguated_reason");
282   if (it != variables.end() && !it->second.empty()) {
283     printer->Print(
284         variables,
285         "// An alternative name is used for field \"$field_name$\" because:\n"
286         "//     $disambiguated_reason$\n");
287   }
288 }
289 
290 }  // namespace java
291 }  // namespace compiler
292 }  // namespace protobuf
293 }  // namespace google
294