Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(65)

Side by Side Diff: third_party/protobuf/src/google/protobuf/compiler/java/java_file.cc

Issue 21208003: Update protobuf to r428, part 1. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Protocol Buffers - Google's data interchange format 1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved. 2 // Copyright 2008 Google Inc. All rights reserved.
3 // http://code.google.com/p/protobuf/ 3 // http://code.google.com/p/protobuf/
4 // 4 //
5 // Redistribution and use in source and binary forms, with or without 5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are 6 // modification, are permitted provided that the following conditions are
7 // met: 7 // met:
8 // 8 //
9 // * Redistributions of source code must retain the above copyright 9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer. 10 // notice, this list of conditions and the following disclaimer.
(...skipping 24 matching lines...) Expand all
35 #include <google/protobuf/compiler/java/java_file.h> 35 #include <google/protobuf/compiler/java/java_file.h>
36 #include <google/protobuf/compiler/java/java_enum.h> 36 #include <google/protobuf/compiler/java/java_enum.h>
37 #include <google/protobuf/compiler/java/java_service.h> 37 #include <google/protobuf/compiler/java/java_service.h>
38 #include <google/protobuf/compiler/java/java_extension.h> 38 #include <google/protobuf/compiler/java/java_extension.h>
39 #include <google/protobuf/compiler/java/java_helpers.h> 39 #include <google/protobuf/compiler/java/java_helpers.h>
40 #include <google/protobuf/compiler/java/java_message.h> 40 #include <google/protobuf/compiler/java/java_message.h>
41 #include <google/protobuf/compiler/code_generator.h> 41 #include <google/protobuf/compiler/code_generator.h>
42 #include <google/protobuf/io/printer.h> 42 #include <google/protobuf/io/printer.h>
43 #include <google/protobuf/io/zero_copy_stream.h> 43 #include <google/protobuf/io/zero_copy_stream.h>
44 #include <google/protobuf/descriptor.pb.h> 44 #include <google/protobuf/descriptor.pb.h>
45 #include <google/protobuf/dynamic_message.h>
45 #include <google/protobuf/stubs/strutil.h> 46 #include <google/protobuf/stubs/strutil.h>
46 47
47 namespace google { 48 namespace google {
48 namespace protobuf { 49 namespace protobuf {
49 namespace compiler { 50 namespace compiler {
50 namespace java { 51 namespace java {
51 52
52 namespace { 53 namespace {
53 54
54 // Recursively searches the given message to see if it contains any extensions. 55
55 bool UsesExtensions(const Message& message) { 56 // Recursively searches the given message to collect extensions.
57 // Returns true if all the extensions can be recognized. The extensions will be
58 // appended in to the extensions parameter.
59 // Returns false when there are unknown fields, in which case the data in the
60 // extensions output parameter is not reliable and should be discarded.
61 bool CollectExtensions(const Message& message,
62 vector<const FieldDescriptor*>* extensions) {
56 const Reflection* reflection = message.GetReflection(); 63 const Reflection* reflection = message.GetReflection();
57 64
58 // We conservatively assume that unknown fields are extensions. 65 // There are unknown fields that could be extensions, thus this call fails.
59 if (reflection->GetUnknownFields(message).field_count() > 0) return true; 66 if (reflection->GetUnknownFields(message).field_count() > 0) return false;
60 67
61 vector<const FieldDescriptor*> fields; 68 vector<const FieldDescriptor*> fields;
62 reflection->ListFields(message, &fields); 69 reflection->ListFields(message, &fields);
63 70
64 for (int i = 0; i < fields.size(); i++) { 71 for (int i = 0; i < fields.size(); i++) {
65 if (fields[i]->is_extension()) return true; 72 if (fields[i]->is_extension()) extensions->push_back(fields[i]);
66 73
67 if (GetJavaType(fields[i]) == JAVATYPE_MESSAGE) { 74 if (GetJavaType(fields[i]) == JAVATYPE_MESSAGE) {
68 if (fields[i]->is_repeated()) { 75 if (fields[i]->is_repeated()) {
69 int size = reflection->FieldSize(message, fields[i]); 76 int size = reflection->FieldSize(message, fields[i]);
70 for (int j = 0; j < size; j++) { 77 for (int j = 0; j < size; j++) {
71 const Message& sub_message = 78 const Message& sub_message =
72 reflection->GetRepeatedMessage(message, fields[i], j); 79 reflection->GetRepeatedMessage(message, fields[i], j);
73 if (UsesExtensions(sub_message)) return true; 80 if (!CollectExtensions(sub_message, extensions)) return false;
74 } 81 }
75 } else { 82 } else {
76 const Message& sub_message = reflection->GetMessage(message, fields[i]); 83 const Message& sub_message = reflection->GetMessage(message, fields[i]);
77 if (UsesExtensions(sub_message)) return true; 84 if (!CollectExtensions(sub_message, extensions)) return false;
78 } 85 }
79 } 86 }
80 } 87 }
81 88
82 return false; 89 return true;
90 }
91
92 // Finds all extensions in the given message and its sub-messages. If the
93 // message contains unknown fields (which could be extensions), then those
94 // extensions are defined in alternate_pool.
95 // The message will be converted to a DynamicMessage backed by alternate_pool
96 // in order to handle this case.
97 void CollectExtensions(const FileDescriptorProto& file_proto,
98 const DescriptorPool& alternate_pool,
99 vector<const FieldDescriptor*>* extensions,
100 const string& file_data) {
101 if (!CollectExtensions(file_proto, extensions)) {
102 // There are unknown fields in the file_proto, which are probably
103 // extensions. We need to parse the data into a dynamic message based on the
104 // builder-pool to find out all extensions.
105 const Descriptor* file_proto_desc = alternate_pool.FindMessageTypeByName(
106 file_proto.GetDescriptor()->full_name());
107 GOOGLE_CHECK(file_proto_desc)
108 << "Find unknown fields in FileDescriptorProto when building "
109 << file_proto.name()
110 << ". It's likely that those fields are custom options, however, "
111 "descriptor.proto is not in the transitive dependencies. "
112 "This normally should not happen. Please report a bug.";
113 DynamicMessageFactory factory;
114 scoped_ptr<Message> dynamic_file_proto(
115 factory.GetPrototype(file_proto_desc)->New());
116 GOOGLE_CHECK(dynamic_file_proto.get() != NULL);
117 GOOGLE_CHECK(dynamic_file_proto->ParseFromString(file_data));
118
119 // Collect the extensions again from the dynamic message. There should be no
120 // more unknown fields this time, i.e. all the custom options should be
121 // parsed as extensions now.
122 extensions->clear();
123 GOOGLE_CHECK(CollectExtensions(*dynamic_file_proto, extensions))
124 << "Find unknown fields in FileDescriptorProto when building "
125 << file_proto.name()
126 << ". It's likely that those fields are custom options, however, "
127 "those options cannot be recognized in the builder pool. "
128 "This normally should not happen. Please report a bug.";
129 }
83 } 130 }
84 131
85 132
86 } // namespace 133 } // namespace
87 134
88 FileGenerator::FileGenerator(const FileDescriptor* file) 135 FileGenerator::FileGenerator(const FileDescriptor* file)
89 : file_(file), 136 : file_(file),
90 java_package_(FileJavaPackage(file)), 137 java_package_(FileJavaPackage(file)),
91 classname_(FileClassName(file)) { 138 classname_(FileClassName(file)) {
92 } 139 }
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 // TODO(kenton): Reuse MessageGenerator objects? 346 // TODO(kenton): Reuse MessageGenerator objects?
300 MessageGenerator(file_->message_type(i)) 347 MessageGenerator(file_->message_type(i))
301 .GenerateStaticVariableInitializers(printer); 348 .GenerateStaticVariableInitializers(printer);
302 } 349 }
303 for (int i = 0; i < file_->extension_count(); i++) { 350 for (int i = 0; i < file_->extension_count(); i++) {
304 // TODO(kenton): Reuse ExtensionGenerator objects? 351 // TODO(kenton): Reuse ExtensionGenerator objects?
305 ExtensionGenerator(file_->extension(i)) 352 ExtensionGenerator(file_->extension(i))
306 .GenerateNonNestedInitializationCode(printer); 353 .GenerateNonNestedInitializationCode(printer);
307 } 354 }
308 355
309 if (UsesExtensions(file_proto)) { 356 // Proto compiler builds a DescriptorPool, which holds all the descriptors to
310 // Must construct an ExtensionRegistry containing all possible extensions 357 // generate, when processing the ".proto" files. We call this DescriptorPool
358 // the parsed pool (a.k.a. file_->pool()).
359 //
360 // Note that when users try to extend the (.*)DescriptorProto in their
361 // ".proto" files, it does not affect the pre-built FileDescriptorProto class
362 // in proto compiler. When we put the descriptor data in the file_proto, those
363 // extensions become unknown fields.
364 //
365 // Now we need to find out all the extension value to the (.*)DescriptorProto
366 // in the file_proto message, and prepare an ExtensionRegistry to return.
367 //
368 // To find those extensions, we need to parse the data into a dynamic message
369 // of the FileDescriptor based on the builder-pool, then we can use
370 // reflections to find all extension fields
371 vector<const FieldDescriptor*> extensions;
372 CollectExtensions(file_proto, *file_->pool(), &extensions, file_data);
373
374 if (extensions.size() > 0) {
375 // Must construct an ExtensionRegistry containing all existing extensions
311 // and return it. 376 // and return it.
312 printer->Print( 377 printer->Print(
313 "com.google.protobuf.ExtensionRegistry registry =\n" 378 "com.google.protobuf.ExtensionRegistry registry =\n"
314 " com.google.protobuf.ExtensionRegistry.newInstance();\n" 379 " com.google.protobuf.ExtensionRegistry.newInstance();\n");
315 "registerAllExtensions(registry);\n"); 380 for (int i = 0; i < extensions.size(); i++) {
316 for (int i = 0; i < file_->dependency_count(); i++) { 381 ExtensionGenerator(extensions[i]).GenerateRegistrationCode(printer);
317 if (ShouldIncludeDependency(file_->dependency(i))) {
318 printer->Print(
319 "$dependency$.registerAllExtensions(registry);\n",
320 "dependency", ClassName(file_->dependency(i)));
321 }
322 } 382 }
323 printer->Print( 383 printer->Print(
324 "return registry;\n"); 384 "return registry;\n");
325 } else { 385 } else {
326 printer->Print( 386 printer->Print(
327 "return null;\n"); 387 "return null;\n");
328 } 388 }
329 389
330 printer->Outdent(); 390 printer->Outdent();
331 printer->Outdent(); 391 printer->Outdent();
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 const string& name_suffix, 428 const string& name_suffix,
369 void (GeneratorClass::*pfn)(io::Printer* printer)) { 429 void (GeneratorClass::*pfn)(io::Printer* printer)) {
370 string filename = package_dir + descriptor->name() + name_suffix + ".java"; 430 string filename = package_dir + descriptor->name() + name_suffix + ".java";
371 file_list->push_back(filename); 431 file_list->push_back(filename);
372 432
373 scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename)); 433 scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
374 io::Printer printer(output.get(), '$'); 434 io::Printer printer(output.get(), '$');
375 435
376 printer.Print( 436 printer.Print(
377 "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" 437 "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
378 "\n"); 438 "// source: $filename$\n"
439 "\n",
440 "filename", descriptor->file()->name());
379 if (!java_package.empty()) { 441 if (!java_package.empty()) {
380 printer.Print( 442 printer.Print(
381 "package $package$;\n" 443 "package $package$;\n"
382 "\n", 444 "\n",
383 "package", java_package); 445 "package", java_package);
384 } 446 }
385 447
386 GeneratorClass generator(descriptor); 448 GeneratorClass generator(descriptor);
387 (generator.*pfn)(&printer); 449 (generator.*pfn)(&printer);
388 } 450 }
(...skipping 30 matching lines...) Expand all
419 } 481 }
420 482
421 bool FileGenerator::ShouldIncludeDependency(const FileDescriptor* descriptor) { 483 bool FileGenerator::ShouldIncludeDependency(const FileDescriptor* descriptor) {
422 return true; 484 return true;
423 } 485 }
424 486
425 } // namespace java 487 } // namespace java
426 } // namespace compiler 488 } // namespace compiler
427 } // namespace protobuf 489 } // namespace protobuf
428 } // namespace google 490 } // namespace google
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698