java_shared_code_generator.cc
Go to the documentation of this file.
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: xiaofeng@google.com (Feng Xiao)
32 
34 
35 #include <memory>
36 
45 
46 namespace google {
47 namespace protobuf {
48 namespace compiler {
49 namespace java {
50 
52  const Options& options)
53  : name_resolver_(new ClassNameResolver), file_(file), options_(options) {}
54 
56 
58  GeneratorContext* context, std::vector<std::string>* file_list,
59  std::vector<std::string>* annotation_file_list) {
60  std::string java_package = FileJavaPackage(file_);
61  std::string package_dir = JavaPackageToDir(java_package);
62 
64  // Generate descriptors.
65  std::string classname = name_resolver_->GetDescriptorClassName(file_);
66  std::string filename = package_dir + classname + ".java";
67  file_list->push_back(filename);
68  std::unique_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
69  GeneratedCodeInfo annotations;
71  &annotations);
72  std::unique_ptr<io::Printer> printer(
73  new io::Printer(output.get(), '$',
74  options_.annotate_code ? &annotation_collector : NULL));
75  std::string info_relative_path = classname + ".java.pb.meta";
76  std::string info_full_path = filename + ".pb.meta";
77  printer->Print(
78  "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
79  "// source: $filename$\n"
80  "\n",
81  "filename", file_->name());
82  if (!java_package.empty()) {
83  printer->Print(
84  "package $package$;\n"
85  "\n",
86  "package", java_package);
87  }
88  PrintGeneratedAnnotation(printer.get(), '$',
89  options_.annotate_code ? info_relative_path : "");
90  printer->Print(
91  "public final class $classname$ {\n"
92  " public static com.google.protobuf.Descriptors.FileDescriptor\n"
93  " descriptor;\n"
94  " static {\n",
95  "classname", classname);
96  printer->Annotate("classname", file_->name());
97  printer->Indent();
98  printer->Indent();
99  GenerateDescriptors(printer.get());
100  printer->Outdent();
101  printer->Outdent();
102  printer->Print(
103  " }\n"
104  "}\n");
105 
106  if (options_.annotate_code) {
107  std::unique_ptr<io::ZeroCopyOutputStream> info_output(
108  context->Open(info_full_path));
109  annotations.SerializeToZeroCopyStream(info_output.get());
110  annotation_file_list->push_back(info_full_path);
111  }
112 
113  printer.reset();
114  output.reset();
115  }
116 }
117 
119  // Embed the descriptor. We simply serialize the entire FileDescriptorProto
120  // and embed it as a string literal, which is parsed and built into real
121  // descriptors at initialization time. We unfortunately have to put it in
122  // a string literal, not a byte array, because apparently using a literal
123  // byte array causes the Java compiler to generate *instructions* to
124  // initialize each and every byte of the array, e.g. as if you typed:
125  // b[0] = 123; b[1] = 456; b[2] = 789;
126  // This makes huge bytecode files and can easily hit the compiler's internal
127  // code size limits (error "code to large"). String literals are apparently
128  // embedded raw, which is what we want.
129  FileDescriptorProto file_proto;
130  file_->CopyTo(&file_proto);
131 
133  file_proto.SerializeToString(&file_data);
134 
135  printer->Print("java.lang.String[] descriptorData = {\n");
136  printer->Indent();
137 
138  // Limit the number of bytes per line.
139  static const int kBytesPerLine = 40;
140  // Limit the number of lines per string part.
141  static const int kLinesPerPart = 400;
142  // Every block of bytes, start a new string literal, in order to avoid the
143  // 64k length limit. Note that this value needs to be <64k.
144  static const int kBytesPerPart = kBytesPerLine * kLinesPerPart;
145  for (int i = 0; i < file_data.size(); i += kBytesPerLine) {
146  if (i > 0) {
147  if (i % kBytesPerPart == 0) {
148  printer->Print(",\n");
149  } else {
150  printer->Print(" +\n");
151  }
152  }
153  printer->Print("\"$data$\"", "data",
154  CEscape(file_data.substr(i, kBytesPerLine)));
155  }
156 
157  printer->Outdent();
158  printer->Print("\n};\n");
159 
160  // -----------------------------------------------------------------
161  // Find out all dependencies.
162  std::vector<std::pair<std::string, std::string> > dependencies;
163  for (int i = 0; i < file_->dependency_count(); i++) {
164  std::string filename = file_->dependency(i)->name();
165  std::string package = FileJavaPackage(file_->dependency(i));
166  std::string classname =
167  name_resolver_->GetDescriptorClassName(file_->dependency(i));
168  std::string full_name;
169  if (package.empty()) {
170  full_name = classname;
171  } else {
172  full_name = package + "." + classname;
173  }
174  dependencies.push_back(std::make_pair(filename, full_name));
175  }
176 
177  // -----------------------------------------------------------------
178  // Invoke internalBuildGeneratedFileFrom() to build the file.
179  printer->Print(
180  "descriptor = com.google.protobuf.Descriptors.FileDescriptor\n"
181  " .internalBuildGeneratedFileFrom(descriptorData,\n");
182  printer->Print(
183  " new com.google.protobuf.Descriptors.FileDescriptor[] {\n");
184 
185  for (int i = 0; i < dependencies.size(); i++) {
186  const std::string& dependency = dependencies[i].second;
187  printer->Print(" $dependency$.getDescriptor(),\n", "dependency",
188  dependency);
189  }
190 
191  printer->Print(" });\n");
192 }
193 
194 } // namespace java
195 } // namespace compiler
196 } // namespace protobuf
197 } // namespace google
zero_copy_stream.h
google::protobuf::io::Printer::Print
void Print(const std::map< std::string, std::string > &variables, const char *text)
Definition: printer.cc:112
google::protobuf::compiler::java::SharedCodeGenerator::GenerateDescriptors
void GenerateDescriptors(io::Printer *printer)
Definition: java_shared_code_generator.cc:118
java_name_resolver.h
google::protobuf::compiler::java::HasDescriptorMethods
bool HasDescriptorMethods(const Descriptor *descriptor, bool enforce_lite)
Definition: java_helpers.h:242
java_helpers.h
NULL
NULL
Definition: test_security_zap.cpp:405
versiongenerate.file_data
string file_data
Definition: versiongenerate.py:84
options
Message * options
Definition: src/google/protobuf/descriptor.cc:3119
google::protobuf::compiler::java::Options
Definition: java_options.h:42
google::protobuf::compiler::GeneratorContext::Open
virtual io::ZeroCopyOutputStream * Open(const std::string &filename)=0
google::protobuf::CEscape
string CEscape(const string &src)
Definition: strutil.cc:615
string
GLsizei const GLchar *const * string
Definition: glcorearb.h:3083
java_shared_code_generator.h
google::protobuf::compiler::java::Options::annotate_code
bool annotate_code
Definition: java_options.h:59
google::protobuf::compiler::java::SharedCodeGenerator::name_resolver_
std::unique_ptr< ClassNameResolver > name_resolver_
Definition: java_shared_code_generator.h:79
google::protobuf::compiler::java::SharedCodeGenerator::Generate
void Generate(GeneratorContext *generator_context, std::vector< std::string > *file_list, std::vector< std::string > *annotation_file_list)
Definition: java_shared_code_generator.cc:57
google::protobuf::io::Printer::Indent
void Indent()
Definition: printer.cc:185
package
string package
strutil.h
google::protobuf::compiler::java::JavaPackageToDir
std::string JavaPackageToDir(std::string package_name)
Definition: java_helpers.cc:265
google::protobuf::compiler::java::PrintGeneratedAnnotation
void PrintGeneratedAnnotation(io::Printer *printer, char delimiter, const std::string &annotation_file)
Definition: java_helpers.cc:124
printer.h
code_generator.h
FileDescriptorProto
Definition: descriptor.pb.h:501
google::protobuf::compiler::java::FileJavaPackage
std::string FileJavaPackage(const FileDescriptor *file, bool immutable)
Definition: java_helpers.cc:245
google::protobuf::FileDescriptor::CopyTo
void CopyTo(FileDescriptorProto *proto) const
Definition: src/google/protobuf/descriptor.cc:2010
google::protobuf::io::Printer
Definition: printer.h:181
i
int i
Definition: gmock-matchers_test.cc:764
google::protobuf::compiler::java::SharedCodeGenerator::options_
const Options options_
Definition: java_shared_code_generator.h:81
java
google::protobuf::FileDescriptor::name
const std::string & name() const
google::protobuf::compiler::java::SharedCodeGenerator::file_
const FileDescriptor * file_
Definition: java_shared_code_generator.h:80
google::protobuf::FileDescriptor::dependency
const FileDescriptor * dependency(int index) const
Definition: src/google/protobuf/descriptor.cc:7271
google::protobuf::compiler::java::SharedCodeGenerator::~SharedCodeGenerator
~SharedCodeGenerator()
Definition: java_shared_code_generator.cc:55
descriptor.h
google::protobuf::FileDescriptor
Definition: src/google/protobuf/descriptor.h:1320
google::protobuf::compiler::java::Options::enforce_lite
bool enforce_lite
Definition: java_options.h:56
google::protobuf::io::AnnotationProtoCollector
Definition: printer.h:76
google::protobuf::compiler::java::ClassNameResolver
Definition: java_name_resolver.h:56
google::protobuf::compiler::java::SharedCodeGenerator::SharedCodeGenerator
SharedCodeGenerator(const FileDescriptor *file, const Options &options)
Definition: java_shared_code_generator.cc:51
descriptor.pb.h
output
const upb_json_parsermethod const upb_symtab upb_sink * output
Definition: ruby/ext/google/protobuf_c/upb.h:10503
GeneratedCodeInfo
Definition: descriptor.pb.h:6355
google::protobuf::compiler::GeneratorContext
Definition: code_generator.h:119
file_
FileDescriptorProto * file_
Definition: annotation_test_util.cc:68
google::protobuf::io::Printer::Outdent
void Outdent()
Definition: printer.cc:187
compiler
Definition: plugin.pb.cc:22
google
Definition: data_proto2_to_proto3_util.h:11
google::protobuf::FileDescriptor::dependency_count
int dependency_count() const
options_
DebugStringOptions options_
Definition: src/google/protobuf/descriptor.cc:2410


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:55