• 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: kenton@google.com (Kenton Varda)
9 //  Based on original Protocol Buffers design by
10 //  Sanjay Ghemawat, Jeff Dean, and others.
11 
12 #include "google/protobuf/compiler/java/full/extension.h"
13 
14 #include "google/protobuf/compiler/java/context.h"
15 #include "google/protobuf/compiler/java/doc_comment.h"
16 #include "google/protobuf/compiler/java/name_resolver.h"
17 #include "google/protobuf/io/printer.h"
18 
19 // Must be last.
20 #include "google/protobuf/port_def.inc"
21 
22 namespace google {
23 namespace protobuf {
24 namespace compiler {
25 namespace java {
26 
ImmutableExtensionGenerator(const FieldDescriptor * descriptor,Context * context)27 ImmutableExtensionGenerator::ImmutableExtensionGenerator(
28     const FieldDescriptor* descriptor, Context* context)
29     : descriptor_(descriptor),
30       name_resolver_(context->GetNameResolver()),
31       context_(context) {
32   if (descriptor_->extension_scope() != nullptr) {
33     scope_ =
34         name_resolver_->GetImmutableClassName(descriptor_->extension_scope());
35   } else {
36     scope_ = name_resolver_->GetImmutableClassName(descriptor_->file());
37   }
38 }
39 
~ImmutableExtensionGenerator()40 ImmutableExtensionGenerator::~ImmutableExtensionGenerator() {}
41 
42 // Initializes the vars referenced in the generated code templates.
InitTemplateVars(const FieldDescriptor * descriptor,const std::string & scope,bool immutable,ClassNameResolver * name_resolver,absl::flat_hash_map<absl::string_view,std::string> * vars_pointer,Context * context)43 void ExtensionGenerator::InitTemplateVars(
44     const FieldDescriptor* descriptor, const std::string& scope, bool immutable,
45     ClassNameResolver* name_resolver,
46     absl::flat_hash_map<absl::string_view, std::string>* vars_pointer,
47     Context* context) {
48   absl::flat_hash_map<absl::string_view, std::string>& vars = *vars_pointer;
49   vars["scope"] = scope;
50   vars["name"] = UnderscoresToCamelCaseCheckReserved(descriptor);
51   vars["containing_type"] =
52       name_resolver->GetClassName(descriptor->containing_type(), immutable);
53   vars["number"] = absl::StrCat(descriptor->number());
54   vars["constant_name"] = FieldConstantName(descriptor);
55   vars["index"] = absl::StrCat(descriptor->index());
56   vars["default"] = descriptor->is_repeated()
57                         ? ""
58                         : DefaultValue(descriptor, immutable, name_resolver,
59                                        context->options());
60   vars["type_constant"] = std::string(FieldTypeName(GetType(descriptor)));
61   vars["packed"] = descriptor->is_packed() ? "true" : "false";
62   vars["enum_map"] = "null";
63   vars["prototype"] = "null";
64 
65   JavaType java_type = GetJavaType(descriptor);
66   std::string singular_type;
67   switch (java_type) {
68     case JAVATYPE_MESSAGE:
69       singular_type =
70           name_resolver->GetClassName(descriptor->message_type(), immutable);
71       vars["prototype"] = absl::StrCat(singular_type, ".getDefaultInstance()");
72       break;
73     case JAVATYPE_ENUM:
74       singular_type =
75           name_resolver->GetClassName(descriptor->enum_type(), immutable);
76       vars["enum_map"] = absl::StrCat(singular_type, ".internalGetValueMap()");
77       break;
78     case JAVATYPE_STRING:
79       singular_type = "java.lang.String";
80       break;
81     case JAVATYPE_BYTES:
82       singular_type = immutable ? "com.google.protobuf.ByteString" : "byte[]";
83       break;
84     default:
85       singular_type = std::string(BoxedPrimitiveTypeName(java_type));
86       break;
87   }
88   vars["type"] = descriptor->is_repeated()
89                      ? absl::StrCat("java.util.List<", singular_type, ">")
90                      : singular_type;
91   vars["singular_type"] = singular_type;
92 }
93 
Generate(io::Printer * printer)94 void ImmutableExtensionGenerator::Generate(io::Printer* printer) {
95   absl::flat_hash_map<absl::string_view, std::string> vars;
96   const bool kUseImmutableNames = true;
97   InitTemplateVars(descriptor_, scope_, kUseImmutableNames, name_resolver_,
98                    &vars, context_);
99   printer->Print(vars, "public static final int $constant_name$ = $number$;\n");
100 
101   WriteFieldDocComment(printer, descriptor_, context_->options());
102   if (descriptor_->extension_scope() == nullptr) {
103     // Non-nested
104     printer->Print(
105         vars,
106         "public static final\n"
107         "  com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
108         "    $containing_type$,\n"
109         "    $type$> $name$ = com.google.protobuf.GeneratedMessage\n"
110         "        .newFileScopedGeneratedExtension(\n"
111         "      $singular_type$.class,\n"
112         "      $prototype$);\n");
113   } else {
114     // Nested
115     printer->Print(
116         vars,
117         "public static final\n"
118         "  com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
119         "    $containing_type$,\n"
120         "    $type$> $name$ = com.google.protobuf.GeneratedMessage\n"
121         "        .newMessageScopedGeneratedExtension(\n"
122         "      $scope$.getDefaultInstance(),\n"
123         "      $index$,\n"
124         "      $singular_type$.class,\n"
125         "      $prototype$);\n");
126   }
127   printer->Annotate("name", descriptor_);
128 }
129 
GenerateNonNestedInitializationCode(io::Printer * printer)130 int ImmutableExtensionGenerator::GenerateNonNestedInitializationCode(
131     io::Printer* printer) {
132   int bytecode_estimate = 0;
133   if (descriptor_->extension_scope() == nullptr) {
134     // Only applies to non-nested extensions.
135     printer->Print(
136         "$name$.internalInit(descriptor.getExtensions().get($index$));\n",
137         "name", UnderscoresToCamelCaseCheckReserved(descriptor_), "index",
138         absl::StrCat(descriptor_->index()));
139     bytecode_estimate += 21;
140   }
141   return bytecode_estimate;
142 }
143 
GenerateRegistrationCode(io::Printer * printer)144 int ImmutableExtensionGenerator::GenerateRegistrationCode(
145     io::Printer* printer) {
146   printer->Print("registry.add($scope$.$name$);\n", "scope", scope_, "name",
147                  UnderscoresToCamelCaseCheckReserved(descriptor_));
148   return 7;
149 }
150 
151 }  // namespace java
152 }  // namespace compiler
153 }  // namespace protobuf
154 }  // namespace google
155 
156 #include "google/protobuf/port_undef.inc"
157