• 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 #ifndef _SHARED_PTR_H
39 #include <google/protobuf/stubs/shared_ptr.h>
40 #endif
41 
42 #include <google/protobuf/stubs/logging.h>
43 #include <google/protobuf/stubs/common.h>
44 #include <google/protobuf/compiler/java/java_context.h>
45 #include <google/protobuf/compiler/java/java_enum_field.h>
46 #include <google/protobuf/compiler/java/java_enum_field_lite.h>
47 #include <google/protobuf/compiler/java/java_helpers.h>
48 #include <google/protobuf/compiler/java/java_lazy_message_field.h>
49 #include <google/protobuf/compiler/java/java_lazy_message_field_lite.h>
50 #include <google/protobuf/compiler/java/java_map_field.h>
51 #include <google/protobuf/compiler/java/java_map_field_lite.h>
52 #include <google/protobuf/compiler/java/java_message_field.h>
53 #include <google/protobuf/compiler/java/java_message_field_lite.h>
54 #include <google/protobuf/compiler/java/java_primitive_field.h>
55 #include <google/protobuf/compiler/java/java_primitive_field_lite.h>
56 #include <google/protobuf/compiler/java/java_string_field.h>
57 #include <google/protobuf/compiler/java/java_string_field_lite.h>
58 #include <google/protobuf/io/printer.h>
59 #include <google/protobuf/stubs/strutil.h>
60 #include <google/protobuf/stubs/substitute.h>
61 
62 
63 namespace google {
64 namespace protobuf {
65 namespace compiler {
66 namespace java {
67 
68 namespace {
69 
MakeImmutableGenerator(const FieldDescriptor * field,int messageBitIndex,int builderBitIndex,Context * context)70 ImmutableFieldGenerator* MakeImmutableGenerator(
71     const FieldDescriptor* field, int messageBitIndex, int builderBitIndex,
72     Context* context) {
73   if (field->is_repeated()) {
74     switch (GetJavaType(field)) {
75       case JAVATYPE_MESSAGE:
76         if (IsMapEntry(field->message_type())) {
77           return new ImmutableMapFieldGenerator(
78               field, messageBitIndex, builderBitIndex, context);
79         } else {
80           if (IsLazy(field, context->EnforceLite())) {
81             return new RepeatedImmutableLazyMessageFieldGenerator(
82                 field, messageBitIndex, builderBitIndex, context);
83           } else {
84             return new RepeatedImmutableMessageFieldGenerator(
85                 field, messageBitIndex, builderBitIndex, context);
86           }
87         }
88       case JAVATYPE_ENUM:
89         return new RepeatedImmutableEnumFieldGenerator(
90             field, messageBitIndex, builderBitIndex, context);
91       case JAVATYPE_STRING:
92         return new RepeatedImmutableStringFieldGenerator(
93             field, messageBitIndex, builderBitIndex, context);
94       default:
95         return new RepeatedImmutablePrimitiveFieldGenerator(
96             field, messageBitIndex, builderBitIndex, context);
97     }
98   } else {
99     if (field->containing_oneof()) {
100       switch (GetJavaType(field)) {
101         case JAVATYPE_MESSAGE:
102           if (IsLazy(field, context->EnforceLite())) {
103             return new ImmutableLazyMessageOneofFieldGenerator(
104                 field, messageBitIndex, builderBitIndex, context);
105           } else {
106             return new ImmutableMessageOneofFieldGenerator(
107                 field, messageBitIndex, builderBitIndex, context);
108           }
109         case JAVATYPE_ENUM:
110           return new ImmutableEnumOneofFieldGenerator(
111               field, messageBitIndex, builderBitIndex, context);
112         case JAVATYPE_STRING:
113           return new ImmutableStringOneofFieldGenerator(
114               field, messageBitIndex, builderBitIndex, context);
115         default:
116           return new ImmutablePrimitiveOneofFieldGenerator(
117               field, messageBitIndex, builderBitIndex, context);
118       }
119     } else {
120       switch (GetJavaType(field)) {
121         case JAVATYPE_MESSAGE:
122           if (IsLazy(field, context->EnforceLite())) {
123             return new ImmutableLazyMessageFieldGenerator(
124                 field, messageBitIndex, builderBitIndex, context);
125           } else {
126             return new ImmutableMessageFieldGenerator(
127                 field, messageBitIndex, builderBitIndex, context);
128           }
129         case JAVATYPE_ENUM:
130           return new ImmutableEnumFieldGenerator(
131               field, messageBitIndex, builderBitIndex, context);
132         case JAVATYPE_STRING:
133           return new ImmutableStringFieldGenerator(
134               field, messageBitIndex, builderBitIndex, context);
135         default:
136           return new ImmutablePrimitiveFieldGenerator(
137               field, messageBitIndex, builderBitIndex, context);
138       }
139     }
140   }
141 }
142 
MakeImmutableLiteGenerator(const FieldDescriptor * field,int messageBitIndex,int builderBitIndex,Context * context)143 ImmutableFieldLiteGenerator* MakeImmutableLiteGenerator(
144     const FieldDescriptor* field, int messageBitIndex, int builderBitIndex,
145     Context* context) {
146   if (field->is_repeated()) {
147     switch (GetJavaType(field)) {
148       case JAVATYPE_MESSAGE:
149         if (IsMapEntry(field->message_type())) {
150           return new ImmutableMapFieldLiteGenerator(
151               field, messageBitIndex, builderBitIndex, context);
152         } else {
153           if (IsLazy(field, context->EnforceLite())) {
154             return new RepeatedImmutableLazyMessageFieldLiteGenerator(
155                 field, messageBitIndex, builderBitIndex, context);
156           } else {
157             return new RepeatedImmutableMessageFieldLiteGenerator(
158                 field, messageBitIndex, builderBitIndex, context);
159           }
160         }
161       case JAVATYPE_ENUM:
162         return new RepeatedImmutableEnumFieldLiteGenerator(
163             field, messageBitIndex, builderBitIndex, context);
164       case JAVATYPE_STRING:
165         return new RepeatedImmutableStringFieldLiteGenerator(
166             field, messageBitIndex, builderBitIndex, context);
167       default:
168         return new RepeatedImmutablePrimitiveFieldLiteGenerator(
169             field, messageBitIndex, builderBitIndex, context);
170     }
171   } else {
172     if (field->containing_oneof()) {
173       switch (GetJavaType(field)) {
174         case JAVATYPE_MESSAGE:
175           if (IsLazy(field, context->EnforceLite())) {
176             return new ImmutableLazyMessageOneofFieldLiteGenerator(
177                 field, messageBitIndex, builderBitIndex, context);
178           } else {
179             return new ImmutableMessageOneofFieldLiteGenerator(
180                 field, messageBitIndex, builderBitIndex, context);
181           }
182         case JAVATYPE_ENUM:
183           return new ImmutableEnumOneofFieldLiteGenerator(
184               field, messageBitIndex, builderBitIndex, context);
185         case JAVATYPE_STRING:
186           return new ImmutableStringOneofFieldLiteGenerator(
187               field, messageBitIndex, builderBitIndex, context);
188         default:
189           return new ImmutablePrimitiveOneofFieldLiteGenerator(
190               field, messageBitIndex, builderBitIndex, context);
191       }
192     } else {
193       switch (GetJavaType(field)) {
194         case JAVATYPE_MESSAGE:
195           if (IsLazy(field, context->EnforceLite())) {
196             return new ImmutableLazyMessageFieldLiteGenerator(
197                 field, messageBitIndex, builderBitIndex, context);
198           } else {
199             return new ImmutableMessageFieldLiteGenerator(
200                 field, messageBitIndex, builderBitIndex, context);
201           }
202         case JAVATYPE_ENUM:
203           return new ImmutableEnumFieldLiteGenerator(
204               field, messageBitIndex, builderBitIndex, context);
205         case JAVATYPE_STRING:
206           return new ImmutableStringFieldLiteGenerator(
207               field, messageBitIndex, builderBitIndex, context);
208         default:
209           return new ImmutablePrimitiveFieldLiteGenerator(
210               field, messageBitIndex, builderBitIndex, context);
211       }
212     }
213   }
214 }
215 
216 
ReportUnexpectedPackedFieldsCall(io::Printer * printer)217 static inline void ReportUnexpectedPackedFieldsCall(io::Printer* printer) {
218   // Reaching here indicates a bug. Cases are:
219   //   - This FieldGenerator should support packing,
220   //     but this method should be overridden.
221   //   - This FieldGenerator doesn't support packing, and this method
222   //     should never have been called.
223   GOOGLE_LOG(FATAL) << "GenerateParsingCodeFromPacked() "
224              << "called on field generator that does not support packing.";
225 }
226 
227 }  // namespace
228 
~ImmutableFieldGenerator()229 ImmutableFieldGenerator::~ImmutableFieldGenerator() {}
230 
231 void ImmutableFieldGenerator::
GenerateParsingCodeFromPacked(io::Printer * printer) const232 GenerateParsingCodeFromPacked(io::Printer* printer) const {
233   ReportUnexpectedPackedFieldsCall(printer);
234 }
235 
~ImmutableFieldLiteGenerator()236 ImmutableFieldLiteGenerator::~ImmutableFieldLiteGenerator() {}
237 
238 void ImmutableFieldLiteGenerator::
GenerateParsingCodeFromPacked(io::Printer * printer) const239 GenerateParsingCodeFromPacked(io::Printer* printer) const {
240   ReportUnexpectedPackedFieldsCall(printer);
241 }
242 
243 // ===================================================================
244 
245 template <>
FieldGeneratorMap(const Descriptor * descriptor,Context * context)246 FieldGeneratorMap<ImmutableFieldGenerator>::FieldGeneratorMap(
247     const Descriptor* descriptor, Context* context)
248     : descriptor_(descriptor),
249       field_generators_(new google::protobuf::scoped_ptr<
250           ImmutableFieldGenerator>[descriptor->field_count()]) {
251 
252   // Construct all the FieldGenerators and assign them bit indices for their
253   // bit fields.
254   int messageBitIndex = 0;
255   int builderBitIndex = 0;
256   for (int i = 0; i < descriptor->field_count(); i++) {
257     ImmutableFieldGenerator* generator = MakeImmutableGenerator(
258         descriptor->field(i), messageBitIndex, builderBitIndex, context);
259     field_generators_[i].reset(generator);
260     messageBitIndex += generator->GetNumBitsForMessage();
261     builderBitIndex += generator->GetNumBitsForBuilder();
262   }
263 }
264 
265 template<>
~FieldGeneratorMap()266 FieldGeneratorMap<ImmutableFieldGenerator>::~FieldGeneratorMap() {}
267 
268 template <>
FieldGeneratorMap(const Descriptor * descriptor,Context * context)269 FieldGeneratorMap<ImmutableFieldLiteGenerator>::FieldGeneratorMap(
270     const Descriptor* descriptor, Context* context)
271     : descriptor_(descriptor),
272       field_generators_(new google::protobuf::scoped_ptr<
273           ImmutableFieldLiteGenerator>[descriptor->field_count()]) {
274   // Construct all the FieldGenerators and assign them bit indices for their
275   // bit fields.
276   int messageBitIndex = 0;
277   int builderBitIndex = 0;
278   for (int i = 0; i < descriptor->field_count(); i++) {
279     ImmutableFieldLiteGenerator* generator = MakeImmutableLiteGenerator(
280         descriptor->field(i), messageBitIndex, builderBitIndex, context);
281     field_generators_[i].reset(generator);
282     messageBitIndex += generator->GetNumBitsForMessage();
283     builderBitIndex += generator->GetNumBitsForBuilder();
284   }
285 }
286 
287 template<>
~FieldGeneratorMap()288 FieldGeneratorMap<ImmutableFieldLiteGenerator>::~FieldGeneratorMap() {}
289 
290 
SetCommonFieldVariables(const FieldDescriptor * descriptor,const FieldGeneratorInfo * info,map<string,string> * variables)291 void SetCommonFieldVariables(const FieldDescriptor* descriptor,
292                              const FieldGeneratorInfo* info,
293                              map<string, string>* variables) {
294   (*variables)["field_name"] = descriptor->name();
295   (*variables)["name"] = info->name;
296   (*variables)["capitalized_name"] = info->capitalized_name;
297   (*variables)["disambiguated_reason"] = info->disambiguated_reason;
298   (*variables)["constant_name"] = FieldConstantName(descriptor);
299   (*variables)["number"] = SimpleItoa(descriptor->number());
300 }
301 
SetCommonOneofVariables(const FieldDescriptor * descriptor,const OneofGeneratorInfo * info,map<string,string> * variables)302 void SetCommonOneofVariables(const FieldDescriptor* descriptor,
303                              const OneofGeneratorInfo* info,
304                              map<string, string>* variables) {
305   (*variables)["oneof_name"] = info->name;
306   (*variables)["oneof_capitalized_name"] = info->capitalized_name;
307   (*variables)["oneof_index"] =
308       SimpleItoa(descriptor->containing_oneof()->index());
309   (*variables)["set_oneof_case_message"] = info->name +
310       "Case_ = " + SimpleItoa(descriptor->number());
311   (*variables)["clear_oneof_case_message"] = info->name +
312       "Case_ = 0";
313   (*variables)["has_oneof_case_message"] = info->name +
314       "Case_ == " + SimpleItoa(descriptor->number());
315 }
316 
PrintExtraFieldInfo(const map<string,string> & variables,io::Printer * printer)317 void PrintExtraFieldInfo(const map<string, string>& variables,
318                          io::Printer* printer) {
319   const map<string, string>::const_iterator it =
320       variables.find("disambiguated_reason");
321   if (it != variables.end() && !it->second.empty()) {
322     printer->Print(
323         variables,
324         "// An alternative name is used for field \"$field_name$\" because:\n"
325         "//     $disambiguated_reason$\n");
326   }
327 }
328 
329 }  // namespace java
330 }  // namespace compiler
331 }  // namespace protobuf
332 }  // namespace google
333