blob: c7aec93ab8fd7c8fcc5f4568bd90d92366e4cadd [file] [log] [blame]
temporal40ee5512008-07-10 02:12:20 +00001// Protocol Buffers - Google's data interchange format
kenton@google.com24bf56f2008-09-24 20:31:01 +00002// Copyright 2008 Google Inc. All rights reserved.
Feng Xiaoe4288622014-10-01 16:26:23 -07003// https://developers.google.com/protocol-buffers/
temporal40ee5512008-07-10 02:12:20 +00004//
kenton@google.com24bf56f2008-09-24 20:31:01 +00005// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
temporal40ee5512008-07-10 02:12:20 +00008//
kenton@google.com24bf56f2008-09-24 20:31:01 +00009// * 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.
temporal40ee5512008-07-10 02:12:20 +000018//
kenton@google.com24bf56f2008-09-24 20:31:01 +000019// 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.
temporal40ee5512008-07-10 02:12:20 +000030
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/cpp/cpp_generator.h>
36
37#include <vector>
jieluo@google.com4de8f552014-07-18 00:47:59 +000038#include <memory>
Feng Xiao6ef984a2014-11-10 17:34:54 -080039#ifndef _SHARED_PTR_H
40#include <google/protobuf/stubs/shared_ptr.h>
41#endif
temporal40ee5512008-07-10 02:12:20 +000042#include <utility>
43
44#include <google/protobuf/compiler/cpp/cpp_file.h>
45#include <google/protobuf/compiler/cpp/cpp_helpers.h>
46#include <google/protobuf/io/printer.h>
47#include <google/protobuf/io/zero_copy_stream.h>
48#include <google/protobuf/descriptor.pb.h>
temporal40ee5512008-07-10 02:12:20 +000049
50namespace google {
51namespace protobuf {
52namespace compiler {
53namespace cpp {
54
temporal40ee5512008-07-10 02:12:20 +000055CppGenerator::CppGenerator() {}
56CppGenerator::~CppGenerator() {}
57
58bool CppGenerator::Generate(const FileDescriptor* file,
59 const string& parameter,
liujisi@google.com33165fe2010-11-02 13:14:58 +000060 GeneratorContext* generator_context,
temporal40ee5512008-07-10 02:12:20 +000061 string* error) const {
62 vector<pair<string, string> > options;
kenton@google.com80b1d622009-07-29 01:13:20 +000063 ParseGeneratorParameter(parameter, &options);
temporal40ee5512008-07-10 02:12:20 +000064
65 // -----------------------------------------------------------------
66 // parse generator options
67
68 // TODO(kenton): If we ever have more options, we may want to create a
69 // class that encapsulates them which we can pass down to all the
70 // generator classes. Currently we pass dllexport_decl down to all of
71 // them via the constructors, but we don't want to have to add another
72 // constructor parameter for every option.
73
74 // If the dllexport_decl option is passed to the compiler, we need to write
75 // it in front of every symbol that should be exported if this .proto is
76 // compiled into a Windows DLL. E.g., if the user invokes the protocol
77 // compiler as:
78 // protoc --cpp_out=dllexport_decl=FOO_EXPORT:outdir foo.proto
79 // then we'll define classes like this:
80 // class FOO_EXPORT Foo {
81 // ...
82 // }
83 // FOO_EXPORT is a macro which should expand to __declspec(dllexport) or
84 // __declspec(dllimport) depending on what is being compiled.
Bo Yang5db21732015-05-21 14:28:59 -070085 //
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +000086 Options file_options;
temporal40ee5512008-07-10 02:12:20 +000087
88 for (int i = 0; i < options.size(); i++) {
89 if (options[i].first == "dllexport_decl") {
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +000090 file_options.dllexport_decl = options[i].second;
91 } else if (options[i].first == "safe_boundary_check") {
92 file_options.safe_boundary_check = true;
Jisi Liu3b3c8ab2016-03-30 11:39:59 -070093 } else if (options[i].first == "annotate_headers") {
94 file_options.annotate_headers = true;
95 } else if (options[i].first == "annotation_pragma_name") {
96 file_options.annotation_pragma_name = options[i].second;
97 } else if (options[i].first == "annotation_guard_name") {
98 file_options.annotation_guard_name = options[i].second;
temporal40ee5512008-07-10 02:12:20 +000099 } else {
100 *error = "Unknown generator option: " + options[i].first;
101 return false;
102 }
103 }
104
105 // -----------------------------------------------------------------
106
107
108 string basename = StripProto(file->name());
temporal40ee5512008-07-10 02:12:20 +0000109
xiaofeng@google.comb55a20f2012-09-22 02:40:50 +0000110 FileGenerator file_generator(file, file_options);
temporal40ee5512008-07-10 02:12:20 +0000111
Feng Xiaoeee38b02015-08-22 18:25:48 -0700112 // Generate header(s).
113 if (file_options.proto_h) {
114 google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(
115 generator_context->Open(basename + ".proto.h"));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -0700116 GeneratedCodeInfo annotations;
117 io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector(
118 &annotations);
119 string info_path = basename + ".proto.h.meta";
120 io::Printer printer(output.get(), '$', file_options.annotate_headers
121 ? &annotation_collector
122 : NULL);
123 file_generator.GenerateProtoHeader(
124 &printer, file_options.annotate_headers ? info_path : "");
125 if (file_options.annotate_headers) {
126 scoped_ptr<io::ZeroCopyOutputStream> info_output(
127 generator_context->Open(info_path));
128 annotations.SerializeToZeroCopyStream(info_output.get());
129 }
Feng Xiaoeee38b02015-08-22 18:25:48 -0700130 }
131
132 basename.append(".pb");
temporal40ee5512008-07-10 02:12:20 +0000133 {
Feng Xiaof157a562014-11-14 11:50:31 -0800134 google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(
jieluo@google.com4de8f552014-07-18 00:47:59 +0000135 generator_context->Open(basename + ".h"));
Jisi Liu3b3c8ab2016-03-30 11:39:59 -0700136 GeneratedCodeInfo annotations;
137 io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector(
138 &annotations);
139 string info_path = basename + ".h.meta";
140 io::Printer printer(output.get(), '$', file_options.annotate_headers
141 ? &annotation_collector
142 : NULL);
143 file_generator.GeneratePBHeader(
144 &printer, file_options.annotate_headers ? info_path : "");
145 if (file_options.annotate_headers) {
146 scoped_ptr<io::ZeroCopyOutputStream> info_output(
147 generator_context->Open(info_path));
148 annotations.SerializeToZeroCopyStream(info_output.get());
149 }
temporal40ee5512008-07-10 02:12:20 +0000150 }
151
152 // Generate cc file.
153 {
Feng Xiaof157a562014-11-14 11:50:31 -0800154 google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(
jieluo@google.com4de8f552014-07-18 00:47:59 +0000155 generator_context->Open(basename + ".cc"));
temporal40ee5512008-07-10 02:12:20 +0000156 io::Printer printer(output.get(), '$');
157 file_generator.GenerateSource(&printer);
158 }
159
160 return true;
161}
162
163} // namespace cpp
164} // namespace compiler
165} // namespace protobuf
166} // namespace google