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: kenton@google.com (Kenton Varda)
9 // Based on original Protocol Buffers design by
10 // Sanjay Ghemawat, Jeff Dean, and others.
11
12 #include <memory>
13 #include <utility>
14
15 #include "google/protobuf/compiler/java/context.h"
16 #include "google/protobuf/compiler/java/generator_common.h"
17 #include "google/protobuf/compiler/java/helpers.h"
18 #include "google/protobuf/compiler/java/full/enum_field.h"
19 #include "google/protobuf/compiler/java/full/field_generator.h"
20 #include "google/protobuf/compiler/java/full/map_field.h"
21 #include "google/protobuf/compiler/java/full/message_field.h"
22 #include "google/protobuf/compiler/java/full/primitive_field.h"
23 #include "google/protobuf/compiler/java/full/string_field.h"
24 #include "google/protobuf/descriptor.h"
25
26 namespace google {
27 namespace protobuf {
28 namespace compiler {
29 namespace java {
30
31 namespace {
32
MakeImmutableGenerator(const FieldDescriptor * field,int messageBitIndex,int builderBitIndex,Context * context)33 std::unique_ptr<ImmutableFieldGenerator> MakeImmutableGenerator(
34 const FieldDescriptor* field, int messageBitIndex, int builderBitIndex,
35 Context* context) {
36 if (field->is_repeated()) {
37 switch (GetJavaType(field)) {
38 case JAVATYPE_MESSAGE:
39 if (IsMapEntry(field->message_type())) {
40 return std::make_unique<ImmutableMapFieldGenerator>(
41 field, messageBitIndex, builderBitIndex, context);
42 } else {
43 return std::make_unique<RepeatedImmutableMessageFieldGenerator>(
44 field, messageBitIndex, builderBitIndex, context);
45 }
46 case JAVATYPE_ENUM:
47 return std::make_unique<RepeatedImmutableEnumFieldGenerator>(
48 field, messageBitIndex, builderBitIndex, context);
49 case JAVATYPE_STRING:
50 return std::make_unique<RepeatedImmutableStringFieldGenerator>(
51 field, messageBitIndex, builderBitIndex, context);
52 default:
53 return std::make_unique<RepeatedImmutablePrimitiveFieldGenerator>(
54 field, messageBitIndex, builderBitIndex, context);
55 }
56 } else {
57 if (IsRealOneof(field)) {
58 switch (GetJavaType(field)) {
59 case JAVATYPE_MESSAGE:
60 return std::make_unique<ImmutableMessageOneofFieldGenerator>(
61 field, messageBitIndex, builderBitIndex, context);
62 case JAVATYPE_ENUM:
63 return std::make_unique<ImmutableEnumOneofFieldGenerator>(
64 field, messageBitIndex, builderBitIndex, context);
65 case JAVATYPE_STRING:
66 return std::make_unique<ImmutableStringOneofFieldGenerator>(
67 field, messageBitIndex, builderBitIndex, context);
68 default:
69 return std::make_unique<ImmutablePrimitiveOneofFieldGenerator>(
70 field, messageBitIndex, builderBitIndex, context);
71 }
72 } else {
73 switch (GetJavaType(field)) {
74 case JAVATYPE_MESSAGE:
75 return std::make_unique<ImmutableMessageFieldGenerator>(
76 field, messageBitIndex, builderBitIndex, context);
77 case JAVATYPE_ENUM:
78 return std::make_unique<ImmutableEnumFieldGenerator>(
79 field, messageBitIndex, builderBitIndex, context);
80 case JAVATYPE_STRING:
81 return std::make_unique<ImmutableStringFieldGenerator>(
82 field, messageBitIndex, builderBitIndex, context);
83 default:
84 return std::make_unique<ImmutablePrimitiveFieldGenerator>(
85 field, messageBitIndex, builderBitIndex, context);
86 }
87 }
88 }
89 }
90
91 } // namespace
92
MakeImmutableFieldGenerators(const Descriptor * descriptor,Context * context)93 FieldGeneratorMap<ImmutableFieldGenerator> MakeImmutableFieldGenerators(
94 const Descriptor* descriptor, Context* context) {
95 // Construct all the FieldGenerators and assign them bit indices for their
96 // bit fields.
97 int messageBitIndex = 0;
98 int builderBitIndex = 0;
99 FieldGeneratorMap<ImmutableFieldGenerator> ret(descriptor);
100 for (int i = 0; i < descriptor->field_count(); i++) {
101 const FieldDescriptor* field = descriptor->field(i);
102 auto generator = MakeImmutableGenerator(field, messageBitIndex,
103 builderBitIndex, context);
104 messageBitIndex += generator->GetNumBitsForMessage();
105 builderBitIndex += generator->GetNumBitsForBuilder();
106 ret.Add(field, std::move(generator));
107 }
108 return ret;
109 }
110
111 } // namespace java
112 } // namespace compiler
113 } // namespace protobuf
114 } // namespace google
115