Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
P
protobuf
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
protobuf
Commits
5e744ff9
Commit
5e744ff9
authored
Dec 18, 2009
by
kenton@google.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit missing files from r251. Sigh.
parent
afd32abb
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
1463 additions
and
0 deletions
+1463
-0
cpp_plugin_unittest.cc
src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
+121
-0
java_plugin_unittest.cc
src/google/protobuf/compiler/java/java_plugin_unittest.cc
+119
-0
mock_code_generator.cc
src/google/protobuf/compiler/mock_code_generator.cc
+207
-0
mock_code_generator.h
src/google/protobuf/compiler/mock_code_generator.h
+108
-0
plugin.cc
src/google/protobuf/compiler/plugin.cc
+135
-0
plugin.h
src/google/protobuf/compiler/plugin.h
+56
-0
plugin.pb.cc
src/google/protobuf/compiler/plugin.pb.cc
+0
-0
plugin.pb.h
src/google/protobuf/compiler/plugin.pb.h
+0
-0
plugin.proto
src/google/protobuf/compiler/plugin.proto
+130
-0
python_plugin_unittest.cc
...google/protobuf/compiler/python/python_plugin_unittest.cc
+116
-0
subprocess.cc
src/google/protobuf/compiler/subprocess.cc
+224
-0
subprocess.h
src/google/protobuf/compiler/subprocess.h
+85
-0
test_plugin.cc
src/google/protobuf/compiler/test_plugin.cc
+44
-0
coded_stream_inl.h
src/google/protobuf/io/coded_stream_inl.h
+64
-0
unittest_no_generic_services.proto
src/google/protobuf/unittest_no_generic_services.proto
+54
-0
No files found.
src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
0 → 100644
View file @
5e744ff9
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
//
// TODO(kenton): Share code with the versions of this test in other languages?
// It seemed like parameterizing it would add more complexity than it is
// worth.
#include <google/protobuf/compiler/cpp/cpp_generator.h>
#include <google/protobuf/compiler/command_line_interface.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
#include <google/protobuf/testing/file.h>
namespace
google
{
namespace
protobuf
{
namespace
compiler
{
namespace
cpp
{
namespace
{
class
TestGenerator
:
public
CodeGenerator
{
public
:
TestGenerator
()
{}
~
TestGenerator
()
{}
virtual
bool
Generate
(
const
FileDescriptor
*
file
,
const
string
&
parameter
,
OutputDirectory
*
output_directory
,
string
*
error
)
const
{
TryInsert
(
"test.pb.h"
,
"includes"
,
output_directory
);
TryInsert
(
"test.pb.h"
,
"namespace_scope"
,
output_directory
);
TryInsert
(
"test.pb.h"
,
"global_scope"
,
output_directory
);
TryInsert
(
"test.pb.h"
,
"class_scope:foo.Bar"
,
output_directory
);
TryInsert
(
"test.pb.h"
,
"class_scope:foo.Bar.Baz"
,
output_directory
);
TryInsert
(
"test.pb.cc"
,
"includes"
,
output_directory
);
TryInsert
(
"test.pb.cc"
,
"namespace_scope"
,
output_directory
);
TryInsert
(
"test.pb.cc"
,
"global_scope"
,
output_directory
);
return
true
;
}
void
TryInsert
(
const
string
&
filename
,
const
string
&
insertion_point
,
OutputDirectory
*
output_directory
)
const
{
scoped_ptr
<
io
::
ZeroCopyOutputStream
>
output
(
output_directory
->
OpenForInsert
(
filename
,
insertion_point
));
io
::
Printer
printer
(
output
.
get
(),
'$'
);
printer
.
Print
(
"// inserted $name$
\n
"
,
"name"
,
insertion_point
);
}
};
// This test verifies that all the expected insertion points exist. It does
// not verify that they are correctly-placed; that would require actually
// compiling the output which is a bit more than I care to do for this test.
TEST
(
CppPluginTest
,
PluginTest
)
{
File
::
WriteStringToFileOrDie
(
"syntax =
\"
proto2
\"
;
\n
"
"package foo;
\n
"
"message Bar {
\n
"
" message Baz {}
\n
"
"}
\n
"
,
TestTempDir
()
+
"/test.proto"
);
google
::
protobuf
::
compiler
::
CommandLineInterface
cli
;
cli
.
SetInputsAreProtoPathRelative
(
true
);
CppGenerator
cpp_generator
;
TestGenerator
test_generator
;
cli
.
RegisterGenerator
(
"--cpp_out"
,
&
cpp_generator
,
""
);
cli
.
RegisterGenerator
(
"--test_out"
,
&
test_generator
,
""
);
string
proto_path
=
"-I"
+
TestTempDir
();
string
cpp_out
=
"--cpp_out="
+
TestTempDir
();
string
test_out
=
"--test_out="
+
TestTempDir
();
const
char
*
argv
[]
=
{
"protoc"
,
proto_path
.
c_str
(),
cpp_out
.
c_str
(),
test_out
.
c_str
(),
"test.proto"
};
EXPECT_EQ
(
0
,
cli
.
Run
(
5
,
argv
));
}
}
// namespace
}
// namespace cpp
}
// namespace compiler
}
// namespace protobuf
}
// namespace google
src/google/protobuf/compiler/java/java_plugin_unittest.cc
0 → 100644
View file @
5e744ff9
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
//
// TODO(kenton): Share code with the versions of this test in other languages?
// It seemed like parameterizing it would add more complexity than it is
// worth.
#include <google/protobuf/compiler/java/java_generator.h>
#include <google/protobuf/compiler/command_line_interface.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
#include <google/protobuf/testing/file.h>
namespace
google
{
namespace
protobuf
{
namespace
compiler
{
namespace
java
{
namespace
{
class
TestGenerator
:
public
CodeGenerator
{
public
:
TestGenerator
()
{}
~
TestGenerator
()
{}
virtual
bool
Generate
(
const
FileDescriptor
*
file
,
const
string
&
parameter
,
OutputDirectory
*
output_directory
,
string
*
error
)
const
{
TryInsert
(
"Test.java"
,
"outer_class_scope"
,
output_directory
);
TryInsert
(
"Test.java"
,
"class_scope:foo.Bar"
,
output_directory
);
TryInsert
(
"Test.java"
,
"class_scope:foo.Bar.Baz"
,
output_directory
);
TryInsert
(
"Test.java"
,
"enum_scope:foo.Qux"
,
output_directory
);
return
true
;
}
void
TryInsert
(
const
string
&
filename
,
const
string
&
insertion_point
,
OutputDirectory
*
output_directory
)
const
{
scoped_ptr
<
io
::
ZeroCopyOutputStream
>
output
(
output_directory
->
OpenForInsert
(
filename
,
insertion_point
));
io
::
Printer
printer
(
output
.
get
(),
'$'
);
printer
.
Print
(
"// inserted $name$
\n
"
,
"name"
,
insertion_point
);
}
};
// This test verifies that all the expected insertion points exist. It does
// not verify that they are correctly-placed; that would require actually
// compiling the output which is a bit more than I care to do for this test.
TEST
(
JavaPluginTest
,
PluginTest
)
{
File
::
WriteStringToFileOrDie
(
"syntax =
\"
proto2
\"
;
\n
"
"package foo;
\n
"
"option java_package =
\"\"
;
\n
"
"option java_outer_classname =
\"
Test
\"
;
\n
"
"message Bar {
\n
"
" message Baz {}
\n
"
"}
\n
"
"enum Qux { BLAH = 1; }
\n
"
,
TestTempDir
()
+
"/test.proto"
);
google
::
protobuf
::
compiler
::
CommandLineInterface
cli
;
cli
.
SetInputsAreProtoPathRelative
(
true
);
JavaGenerator
java_generator
;
TestGenerator
test_generator
;
cli
.
RegisterGenerator
(
"--java_out"
,
&
java_generator
,
""
);
cli
.
RegisterGenerator
(
"--test_out"
,
&
test_generator
,
""
);
string
proto_path
=
"-I"
+
TestTempDir
();
string
java_out
=
"--java_out="
+
TestTempDir
();
string
test_out
=
"--test_out="
+
TestTempDir
();
const
char
*
argv
[]
=
{
"protoc"
,
proto_path
.
c_str
(),
java_out
.
c_str
(),
test_out
.
c_str
(),
"test.proto"
};
EXPECT_EQ
(
0
,
cli
.
Run
(
5
,
argv
));
}
}
// namespace
}
// namespace java
}
// namespace compiler
}
// namespace protobuf
}
// namespace google
src/google/protobuf/compiler/mock_code_generator.cc
0 → 100644
View file @
5e744ff9
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
#include <google/protobuf/compiler/mock_code_generator.h>
#include <google/protobuf/testing/file.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
#include <gtest/gtest.h>
#include <google/protobuf/stubs/stl_util-inl.h>
namespace
google
{
namespace
protobuf
{
namespace
compiler
{
static
const
char
*
kFirstInsertionPointName
=
"first_mock_insertion_point"
;
static
const
char
*
kSecondInsertionPointName
=
"second_mock_insertion_point"
;
static
const
char
*
kFirstInsertionPoint
=
"# @@protoc_insertion_point(first_mock_insertion_point) is here
\n
"
;
static
const
char
*
kSecondInsertionPoint
=
"# @@protoc_insertion_point(second_mock_insertion_point) is here
\n
"
;
MockCodeGenerator
::
MockCodeGenerator
(
const
string
&
name
)
:
name_
(
name
)
{}
MockCodeGenerator
::~
MockCodeGenerator
()
{}
void
MockCodeGenerator
::
ExpectGenerated
(
const
string
&
name
,
const
string
&
parameter
,
const
string
&
insertions
,
const
string
&
file
,
const
string
&
first_message_name
,
const
string
&
output_directory
)
{
string
content
;
ASSERT_TRUE
(
File
::
ReadFileToString
(
output_directory
+
"/"
+
GetOutputFileName
(
name
,
file
),
&
content
));
vector
<
string
>
lines
;
SplitStringUsing
(
content
,
"
\n
"
,
&
lines
);
while
(
!
lines
.
empty
()
&&
lines
.
back
().
empty
())
{
lines
.
pop_back
();
}
for
(
int
i
=
0
;
i
<
lines
.
size
();
i
++
)
{
lines
[
i
]
+=
"
\n
"
;
}
vector
<
string
>
insertion_list
;
if
(
!
insertions
.
empty
())
{
SplitStringUsing
(
insertions
,
","
,
&
insertion_list
);
}
ASSERT_EQ
(
lines
.
size
(),
3
+
insertion_list
.
size
()
*
2
);
EXPECT_EQ
(
GetOutputFileContent
(
name
,
parameter
,
file
,
first_message_name
),
lines
[
0
]);
EXPECT_EQ
(
kFirstInsertionPoint
,
lines
[
1
+
insertion_list
.
size
()]);
EXPECT_EQ
(
kSecondInsertionPoint
,
lines
[
2
+
insertion_list
.
size
()
*
2
]);
for
(
int
i
=
0
;
i
<
insertion_list
.
size
();
i
++
)
{
EXPECT_EQ
(
GetOutputFileContent
(
insertion_list
[
i
],
"first_insert"
,
file
,
first_message_name
),
lines
[
1
+
i
]);
EXPECT_EQ
(
GetOutputFileContent
(
insertion_list
[
i
],
"second_insert"
,
file
,
first_message_name
),
lines
[
2
+
insertion_list
.
size
()
+
i
]);
}
}
bool
MockCodeGenerator
::
Generate
(
const
FileDescriptor
*
file
,
const
string
&
parameter
,
OutputDirectory
*
output_directory
,
string
*
error
)
const
{
for
(
int
i
=
0
;
i
<
file
->
message_type_count
();
i
++
)
{
if
(
HasPrefixString
(
file
->
message_type
(
i
)
->
name
(),
"MockCodeGenerator_"
))
{
string
command
=
StripPrefixString
(
file
->
message_type
(
i
)
->
name
(),
"MockCodeGenerator_"
);
if
(
command
==
"Error"
)
{
*
error
=
"Saw message type MockCodeGenerator_Error."
;
return
false
;
}
else
if
(
command
==
"Exit"
)
{
cerr
<<
"Saw message type MockCodeGenerator_Exit."
<<
endl
;
exit
(
123
);
}
else
if
(
command
==
"Abort"
)
{
cerr
<<
"Saw message type MockCodeGenerator_Abort."
<<
endl
;
abort
();
}
else
{
GOOGLE_LOG
(
FATAL
)
<<
"Unknown MockCodeGenerator command: "
<<
command
;
}
}
}
if
(
HasPrefixString
(
parameter
,
"insert="
))
{
vector
<
string
>
insert_into
;
SplitStringUsing
(
StripPrefixString
(
parameter
,
"insert="
),
","
,
&
insert_into
);
for
(
int
i
=
0
;
i
<
insert_into
.
size
();
i
++
)
{
{
scoped_ptr
<
io
::
ZeroCopyOutputStream
>
output
(
output_directory
->
OpenForInsert
(
GetOutputFileName
(
insert_into
[
i
],
file
),
kFirstInsertionPointName
));
io
::
Printer
printer
(
output
.
get
(),
'$'
);
printer
.
PrintRaw
(
GetOutputFileContent
(
name_
,
"first_insert"
,
file
));
if
(
printer
.
failed
())
{
*
error
=
"MockCodeGenerator detected write error."
;
return
false
;
}
}
{
scoped_ptr
<
io
::
ZeroCopyOutputStream
>
output
(
output_directory
->
OpenForInsert
(
GetOutputFileName
(
insert_into
[
i
],
file
),
kSecondInsertionPointName
));
io
::
Printer
printer
(
output
.
get
(),
'$'
);
printer
.
PrintRaw
(
GetOutputFileContent
(
name_
,
"second_insert"
,
file
));
if
(
printer
.
failed
())
{
*
error
=
"MockCodeGenerator detected write error."
;
return
false
;
}
}
}
}
else
{
scoped_ptr
<
io
::
ZeroCopyOutputStream
>
output
(
output_directory
->
Open
(
GetOutputFileName
(
name_
,
file
)));
io
::
Printer
printer
(
output
.
get
(),
'$'
);
printer
.
PrintRaw
(
GetOutputFileContent
(
name_
,
parameter
,
file
));
printer
.
PrintRaw
(
kFirstInsertionPoint
);
printer
.
PrintRaw
(
kSecondInsertionPoint
);
if
(
printer
.
failed
())
{
*
error
=
"MockCodeGenerator detected write error."
;
return
false
;
}
}
return
true
;
}
string
MockCodeGenerator
::
GetOutputFileName
(
const
string
&
generator_name
,
const
FileDescriptor
*
file
)
{
return
GetOutputFileName
(
generator_name
,
file
->
name
());
}
string
MockCodeGenerator
::
GetOutputFileName
(
const
string
&
generator_name
,
const
string
&
file
)
{
return
file
+
".MockCodeGenerator."
+
generator_name
;
}
string
MockCodeGenerator
::
GetOutputFileContent
(
const
string
&
generator_name
,
const
string
&
parameter
,
const
FileDescriptor
*
file
)
{
return
GetOutputFileContent
(
generator_name
,
parameter
,
file
->
name
(),
file
->
message_type_count
()
>
0
?
file
->
message_type
(
0
)
->
name
()
:
"(none)"
);
}
string
MockCodeGenerator
::
GetOutputFileContent
(
const
string
&
generator_name
,
const
string
&
parameter
,
const
string
&
file
,
const
string
&
first_message_name
)
{
return
strings
::
Substitute
(
"$0: $1, $2, $3
\n
"
,
generator_name
,
parameter
,
file
,
first_message_name
);
}
}
// namespace compiler
}
// namespace protobuf
}
// namespace google
src/google/protobuf/compiler/mock_code_generator.h
0 → 100644
View file @
5e744ff9
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
#ifndef GOOGLE_PROTOBUF_COMPILER_MOCK_CODE_GENERATOR_H__
#define GOOGLE_PROTOBUF_COMPILER_MOCK_CODE_GENERATOR_H__
#include <string>
#include <google/protobuf/compiler/code_generator.h>
namespace
google
{
namespace
protobuf
{
namespace
compiler
{
// A mock CodeGenerator, used by command_line_interface_unittest. This is in
// its own file so that it can be used both directly and as a plugin.
//
// Generate() produces some output which can be checked by ExpectCalled(). The
// generator can run in a different process (e.g. a plugin).
//
// If the parameter is "insert=NAMES", the MockCodeGenerator will insert lines
// into the files generated by other MockCodeGenerators instead of creating
// its own file. NAMES is a comma-separated list of the names of those other
// MockCodeGenerators.
//
// MockCodeGenerator will also modify its behavior slightly if the input file
// contains a message type with one of the following names:
// MockCodeGenerator_Error: Causes Generate() to return false and set the
// error message to "Saw message type MockCodeGenerator_Error."
// MockCodeGenerator_Exit: Generate() prints "Saw message type
// MockCodeGenerator_Exit." to stderr and then calls exit(123).
// MockCodeGenerator_Abort: Generate() prints "Saw message type
// MockCodeGenerator_Abort." to stderr and then calls abort().
class
MockCodeGenerator
:
public
CodeGenerator
{
public
:
MockCodeGenerator
(
const
string
&
name
);
virtual
~
MockCodeGenerator
();
// Expect (via gTest) that a MockCodeGenerator with the given name was called
// with the given parameters by inspecting the output location.
//
// |insertions| is a comma-separated list of names of MockCodeGenerators which
// should have inserted lines into this file.
static
void
ExpectGenerated
(
const
string
&
name
,
const
string
&
parameter
,
const
string
&
insertions
,
const
string
&
file
,
const
string
&
first_message_name
,
const
string
&
output_directory
);
// Get the name of the file which would be written by the given generator.
static
string
GetOutputFileName
(
const
string
&
generator_name
,
const
FileDescriptor
*
file
);
static
string
GetOutputFileName
(
const
string
&
generator_name
,
const
string
&
file
);
// implements CodeGenerator ----------------------------------------
virtual
bool
Generate
(
const
FileDescriptor
*
file
,
const
string
&
parameter
,
OutputDirectory
*
output_directory
,
string
*
error
)
const
;
private
:
string
name_
;
static
string
GetOutputFileContent
(
const
string
&
generator_name
,
const
string
&
parameter
,
const
FileDescriptor
*
file
);
static
string
GetOutputFileContent
(
const
string
&
generator_name
,
const
string
&
parameter
,
const
string
&
file
,
const
string
&
first_message_name
);
};
}
// namespace compiler
}
// namespace protobuf
}
// namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_MOCK_CODE_GENERATOR_H__
src/google/protobuf/compiler/plugin.cc
0 → 100644
View file @
5e744ff9
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
#include <google/protobuf/compiler/plugin.h>
#include <iostream>
#include <set>
#include <unistd.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/plugin.pb.h>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
namespace
google
{
namespace
protobuf
{
namespace
compiler
{
class
GeneratorResponseOutputDirectory
:
public
OutputDirectory
{
public
:
GeneratorResponseOutputDirectory
(
CodeGeneratorResponse
*
response
)
:
response_
(
response
)
{}
virtual
~
GeneratorResponseOutputDirectory
()
{}
// implements OutputDirectory --------------------------------------
virtual
io
::
ZeroCopyOutputStream
*
Open
(
const
string
&
filename
)
{
CodeGeneratorResponse
::
File
*
file
=
response_
->
add_file
();
file
->
set_name
(
filename
);
return
new
io
::
StringOutputStream
(
file
->
mutable_content
());
}
virtual
io
::
ZeroCopyOutputStream
*
OpenForInsert
(
const
string
&
filename
,
const
string
&
insertion_point
)
{
CodeGeneratorResponse
::
File
*
file
=
response_
->
add_file
();
file
->
set_name
(
filename
);
file
->
set_insertion_point
(
insertion_point
);
return
new
io
::
StringOutputStream
(
file
->
mutable_content
());
}
private
:
CodeGeneratorResponse
*
response_
;
};
int
PluginMain
(
int
argc
,
char
*
argv
[],
const
CodeGenerator
*
generator
)
{
if
(
argc
>
1
)
{
cerr
<<
argv
[
0
]
<<
": Unknown option: "
<<
argv
[
1
]
<<
endl
;
return
1
;
}
CodeGeneratorRequest
request
;
if
(
!
request
.
ParseFromFileDescriptor
(
STDIN_FILENO
))
{
cerr
<<
argv
[
0
]
<<
": protoc sent unparseable request to plugin."
<<
endl
;
return
1
;
}
DescriptorPool
pool
;
for
(
int
i
=
0
;
i
<
request
.
proto_file_size
();
i
++
)
{
const
FileDescriptor
*
file
=
pool
.
BuildFile
(
request
.
proto_file
(
i
));
if
(
file
==
NULL
)
{
// BuildFile() already wrote an error message.
return
1
;
}
}
CodeGeneratorResponse
response
;
GeneratorResponseOutputDirectory
output_directory
(
&
response
);
for
(
int
i
=
0
;
i
<
request
.
file_to_generate_size
();
i
++
)
{
const
FileDescriptor
*
file
=
pool
.
FindFileByName
(
request
.
file_to_generate
(
i
));
if
(
file
==
NULL
)
{
cerr
<<
argv
[
0
]
<<
": protoc asked plugin to generate a file but "
"did not provide a descriptor for the file: "
<<
request
.
file_to_generate
(
i
)
<<
endl
;
return
1
;
}
string
error
;
bool
succeeded
=
generator
->
Generate
(
file
,
request
.
parameter
(),
&
output_directory
,
&
error
);
if
(
!
succeeded
&&
error
.
empty
())
{
error
=
"Code generator returned false but provided no error "
"description."
;
}
if
(
!
error
.
empty
())
{
response
.
set_error
(
file
->
name
()
+
": "
+
error
);
break
;
}
}
if
(
!
response
.
SerializeToFileDescriptor
(
STDOUT_FILENO
))
{
cerr
<<
argv
[
0
]
<<
": Error writing to stdout."
<<
endl
;
return
1
;
}
return
0
;
}
}
// namespace compiler
}
// namespace protobuf
}
// namespace google
src/google/protobuf/compiler/plugin.h
0 → 100644
View file @
5e744ff9
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
#ifndef GOOGLE_PROTOBUF_COMPILER_PLUGIN_H__
#define GOOGLE_PROTOBUF_COMPILER_PLUGIN_H__
#include <google/protobuf/stubs/common.h>
namespace
google
{
namespace
protobuf
{
namespace
compiler
{
class
CodeGenerator
;
// code_generator.h
// To implement a protoc plugin in C++, simply write an implementation of
// CodeGenerator, then create a main() function like:
// int main(int argc, char* argv[]) {
// MyCodeGenerator generator;
// return PluginMain(argc, argv, &generator);
// }
int
PluginMain
(
int
argc
,
char
*
argv
[],
const
CodeGenerator
*
generator
);
}
// namespace compiler
}
// namespace protobuf
}
// namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_PLUGIN_H__
src/google/protobuf/compiler/plugin.pb.cc
0 → 100644
View file @
5e744ff9
This diff is collapsed.
Click to expand it.
src/google/protobuf/compiler/plugin.pb.h
0 → 100644
View file @
5e744ff9
This diff is collapsed.
Click to expand it.
src/google/protobuf/compiler/plugin.proto
0 → 100644
View file @
5e744ff9
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
//
// protoc (aka the Protocol Compiler) can be extended via plugins. A plugin is
// just a program that reads a CodeGeneratorRequest from stdin and writes a
// CodeGeneratorResponse to stdout.
//
// Plugins written using C++ can use google/protobuf/compiler/plugin.h instead
// of dealing with the raw protocol defined here.
//
// A plugin executable needs only to be placed somewhere in the path. The
// plugin should be named "protoc-gen-$NAME", and will then be used when the
// flag "--${NAME}_out" is passed to protoc.
package
google
.
protobuf.compiler
;
import
"google/protobuf/descriptor.proto"
;
// An encoded CodeGeneratorRequest is written to the plugin's stdin.
message
CodeGeneratorRequest
{
// The .proto files that were explicitly listed on the command-line. The
// code generator should generate code only for these files. Each file's
// descriptor will be included in proto_file, below.
repeated
string
file_to_generate
=
1
;
// The generator parameter passed on the command-line.
optional
string
parameter
=
2
;
// FileDescriptorProtos for all files in files_to_generate and everything
// they import. The files will appear in topological order, so each file
// appears before any file that imports it.
//
// protoc guarantees that all proto_files will be written after
// the fields above, even though this is not technically guaranteed by the
// protobuf wire format. This theoretically could allow a plugin to stream
// in the FileDescriptorProtos and handle them one by one rather than read
// the entire set into memory at once. However, as of this writing, this
// is not similarly optimized on protoc's end -- it will store all fields in
// memory at once before sending them to the plugin.
repeated
FileDescriptorProto
proto_file
=
15
;
}
// The plugin writes an encoded CodeGeneratorResponse to stdout.
message
CodeGeneratorResponse
{
// Error message. If non-empty, code generation failed. The plugin process
// should exit with status code zero even if it reports an error in this way.
//
// This should be used to indicate errors in .proto files which prevent the
// code generator from generating correct code. Errors which indicate a
// problem in protoc itself -- such as the input CodeGeneratorRequest being
// unparseable -- should be reported by writing a message to stderr and
// exiting with a non-zero status code.
optional
string
error
=
1
;
// Represents a single generated file.
message
File
{
// The file name, relative to the output directory. The name must not
// contain "." or ".." components and must be relative, not be absolute (so,
// the file cannot lie outside the output directory). "/" must be used as
// the path separator, not "\".
//
// If the name is omitted, the content will be appended to the previous
// file. This allows the generator to break large files into small chunks,
// and allows the generated text to be streamed back to protoc so that large
// files need not reside completely in memory at one time. Note that as of
// this writing protoc does not optimize for this -- it will read the entire
// CodeGeneratorResponse before writing files to disk.
optional
string
name
=
1
;
// If non-empty, indicates that the named file should already exist, and the
// content here is to be inserted into that file at a defined insertion
// point. This feature allows a code generator to extend the output
// produced by another code generator. The original generator may provide
// insertion points by placing special annotations in the file that look
// like:
// @@protoc_insertion_point(NAME)
// The annotation can have arbitrary text before and after it on the line,
// which allows it to be placed in a comment. NAME should be replaced with
// an identifier naming the point -- this is what other generators will use
// as the insertion_point. Code inserted at this point will be placed
// immediately above the line containing the insertion point (thus multiple
// insertions to the same point will come out in the order they were added).
// The double-@ is intended to make it unlikely that the generated code
// could contain things that look like insertion points by accident.
//
// For example, the C++ code generator places the following line in the
// .pb.h files that it generates:
// // @@protoc_insertion_point(package_level_decls)
// This line appears within the scope of the file's package namespace, but
// outside of any particular class. Another plugin can then specify the
// insertion_point "package_level_decls" to generate additional classes or
// other declarations that should be placed in this scope.
//
// If |insertion_point| is present, |name| must also be present.
optional
string
insertion_point
=
2
;
// The file contents.
optional
string
content
=
15
;
}
repeated
File
file
=
15
;
}
src/google/protobuf/compiler/python/python_plugin_unittest.cc
0 → 100644
View file @
5e744ff9
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
//
// TODO(kenton): Share code with the versions of this test in other languages?
// It seemed like parameterizing it would add more complexity than it is
// worth.
#include <google/protobuf/compiler/python/python_generator.h>
#include <google/protobuf/compiler/command_line_interface.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
#include <google/protobuf/testing/file.h>
namespace
google
{
namespace
protobuf
{
namespace
compiler
{
namespace
python
{
namespace
{
class
TestGenerator
:
public
CodeGenerator
{
public
:
TestGenerator
()
{}
~
TestGenerator
()
{}
virtual
bool
Generate
(
const
FileDescriptor
*
file
,
const
string
&
parameter
,
OutputDirectory
*
output_directory
,
string
*
error
)
const
{
TryInsert
(
"test_pb2.py"
,
"imports"
,
output_directory
);
TryInsert
(
"test_pb2.py"
,
"module_scope"
,
output_directory
);
TryInsert
(
"test_pb2.py"
,
"class_scope:foo.Bar"
,
output_directory
);
TryInsert
(
"test_pb2.py"
,
"class_scope:foo.Bar.Baz"
,
output_directory
);
return
true
;
}
void
TryInsert
(
const
string
&
filename
,
const
string
&
insertion_point
,
OutputDirectory
*
output_directory
)
const
{
scoped_ptr
<
io
::
ZeroCopyOutputStream
>
output
(
output_directory
->
OpenForInsert
(
filename
,
insertion_point
));
io
::
Printer
printer
(
output
.
get
(),
'$'
);
printer
.
Print
(
"// inserted $name$
\n
"
,
"name"
,
insertion_point
);
}
};
// This test verifies that all the expected insertion points exist. It does
// not verify that they are correctly-placed; that would require actually
// compiling the output which is a bit more than I care to do for this test.
TEST
(
PythonPluginTest
,
PluginTest
)
{
File
::
WriteStringToFileOrDie
(
"syntax =
\"
proto2
\"
;
\n
"
"package foo;
\n
"
"message Bar {
\n
"
" message Baz {}
\n
"
"}
\n
"
,
TestTempDir
()
+
"/test.proto"
);
google
::
protobuf
::
compiler
::
CommandLineInterface
cli
;
cli
.
SetInputsAreProtoPathRelative
(
true
);
python
::
Generator
python_generator
;
TestGenerator
test_generator
;
cli
.
RegisterGenerator
(
"--python_out"
,
&
python_generator
,
""
);
cli
.
RegisterGenerator
(
"--test_out"
,
&
test_generator
,
""
);
string
proto_path
=
"-I"
+
TestTempDir
();
string
python_out
=
"--python_out="
+
TestTempDir
();
string
test_out
=
"--test_out="
+
TestTempDir
();
const
char
*
argv
[]
=
{
"protoc"
,
proto_path
.
c_str
(),
python_out
.
c_str
(),
test_out
.
c_str
(),
"test.proto"
};
EXPECT_EQ
(
0
,
cli
.
Run
(
5
,
argv
));
}
}
// namespace
}
// namespace python
}
// namespace compiler
}
// namespace protobuf
}
// namespace google
src/google/protobuf/compiler/subprocess.cc
0 → 100644
View file @
5e744ff9
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
#include <google/protobuf/compiler/subprocess.h>
#include <algorithm>
#include <errno.h>
#include <sys/wait.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/message.h>
#include <google/protobuf/stubs/substitute.h>
namespace
google
{
namespace
protobuf
{
namespace
compiler
{
Subprocess
::
Subprocess
()
:
child_pid_
(
-
1
),
child_stdin_
(
-
1
),
child_stdout_
(
-
1
)
{}
Subprocess
::~
Subprocess
()
{
if
(
child_stdin_
!=
-
1
)
{
close
(
child_stdin_
);
}
if
(
child_stdout_
!=
-
1
)
{
close
(
child_stdout_
);
}
}
void
Subprocess
::
Start
(
const
string
&
program
,
SearchMode
search_mode
)
{
// Note that we assume that there are no other threads, thus we don't have to
// do crazy stuff like using socket pairs or avoiding libc locks.
// [0] is read end, [1] is write end.
int
stdin_pipe
[
2
];
int
stdout_pipe
[
2
];
pipe
(
stdin_pipe
);
pipe
(
stdout_pipe
);
char
*
argv
[
2
]
=
{
strdup
(
program
.
c_str
()),
NULL
};
child_pid_
=
fork
();
if
(
child_pid_
==
-
1
)
{
GOOGLE_LOG
(
FATAL
)
<<
"fork: "
<<
strerror
(
errno
);
}
else
if
(
child_pid_
==
0
)
{
// We are the child.
dup2
(
stdin_pipe
[
0
],
STDIN_FILENO
);
dup2
(
stdout_pipe
[
1
],
STDOUT_FILENO
);
close
(
stdin_pipe
[
0
]);
close
(
stdin_pipe
[
1
]);
close
(
stdout_pipe
[
0
]);
close
(
stdout_pipe
[
1
]);
switch
(
search_mode
)
{
case
SEARCH_PATH
:
execvp
(
argv
[
0
],
argv
);
break
;
case
EXACT_NAME
:
execv
(
argv
[
0
],
argv
);
break
;
}
// Write directly to STDERR_FILENO to avoid stdio code paths that may do
// stuff that is unsafe here.
write
(
STDERR_FILENO
,
argv
[
0
],
strlen
(
argv
[
0
]));
const
char
*
message
=
": program not found or is not executable
\n
"
;
write
(
STDERR_FILENO
,
message
,
strlen
(
message
));
// Must use _exit() rather than exit() to avoid flushing output buffers
// that will also be flushed by the parent.
_exit
(
1
);
}
else
{
free
(
argv
[
0
]);
close
(
stdin_pipe
[
0
]);
close
(
stdout_pipe
[
1
]);
child_stdin_
=
stdin_pipe
[
1
];
child_stdout_
=
stdout_pipe
[
0
];
}
}
bool
Subprocess
::
Communicate
(
const
Message
&
input
,
Message
*
output
,
string
*
error
)
{
GOOGLE_CHECK_NE
(
child_stdin_
,
-
1
)
<<
"Must call Start() first."
;
// Make sure SIGPIPE is disabled so that if the child dies it doesn't kill us.
sighandler_t
old_pipe_handler
=
signal
(
SIGPIPE
,
SIG_IGN
);
string
input_data
=
input
.
SerializeAsString
();
string
output_data
;
int
input_pos
=
0
;
int
max_fd
=
max
(
child_stdin_
,
child_stdout_
);
while
(
child_stdout_
!=
-
1
)
{
fd_set
read_fds
;
fd_set
write_fds
;
FD_ZERO
(
&
read_fds
);
FD_ZERO
(
&
write_fds
);
if
(
child_stdout_
!=
-
1
)
{
FD_SET
(
child_stdout_
,
&
read_fds
);
}
if
(
child_stdin_
!=
-
1
)
{
FD_SET
(
child_stdin_
,
&
write_fds
);
}
if
(
select
(
max_fd
+
1
,
&
read_fds
,
&
write_fds
,
NULL
,
NULL
)
<
0
)
{
if
(
errno
==
EINTR
)
{
// Interrupted by signal. Try again.
continue
;
}
else
{
GOOGLE_LOG
(
FATAL
)
<<
"select: "
<<
strerror
(
errno
);
}
}
if
(
child_stdin_
!=
-
1
&&
FD_ISSET
(
child_stdin_
,
&
write_fds
))
{
int
n
=
write
(
child_stdin_
,
input_data
.
data
()
+
input_pos
,
input_data
.
size
()
-
input_pos
);
if
(
n
<
0
)
{
// Child closed pipe. Presumably it will report an error later.
// Pretend we're done for now.
input_pos
=
input_data
.
size
();
}
else
{
input_pos
+=
n
;
}
if
(
input_pos
==
input_data
.
size
())
{
// We're done writing. Close.
close
(
child_stdin_
);
child_stdin_
=
-
1
;
}
}
if
(
child_stdout_
!=
-
1
&&
FD_ISSET
(
child_stdout_
,
&
read_fds
))
{
char
buffer
[
4096
];
int
n
=
read
(
child_stdout_
,
buffer
,
sizeof
(
buffer
));
if
(
n
>
0
)
{
output_data
.
append
(
buffer
,
n
);
}
else
{
// We're done reading. Close.
close
(
child_stdout_
);
child_stdout_
=
-
1
;
}
}
}
if
(
child_stdin_
!=
-
1
)
{
// Child did not finish reading input before it closed the output.
// Presumably it exited with an error.
close
(
child_stdin_
);
child_stdin_
=
-
1
;
}
int
status
;
while
(
waitpid
(
child_pid_
,
&
status
,
0
)
==
-
1
)
{
if
(
errno
!=
EINTR
)
{
GOOGLE_LOG
(
FATAL
)
<<
"waitpid: "
<<
strerror
(
errno
);
}
}
// Restore SIGPIPE handling.
signal
(
SIGPIPE
,
old_pipe_handler
);
if
(
WIFEXITED
(
status
))
{
if
(
WEXITSTATUS
(
status
)
!=
0
)
{
int
error_code
=
WEXITSTATUS
(
status
);
*
error
=
strings
::
Substitute
(
"Plugin failed with status code $0."
,
error_code
);
return
false
;
}
}
else
if
(
WIFSIGNALED
(
status
))
{
int
signal
=
WTERMSIG
(
status
);
*
error
=
strings
::
Substitute
(
"Plugin killed by signal $0."
,
signal
);
return
false
;
}
else
{
*
error
=
"Neither WEXITSTATUS nor WTERMSIG is true?"
;
return
false
;
}
if
(
!
output
->
ParseFromString
(
output_data
))
{
*
error
=
"Plugin output is unparseable."
;
return
false
;
}
return
true
;
}
}
// namespace compiler
}
// namespace protobuf
}
// namespace google
src/google/protobuf/compiler/subprocess.h
0 → 100644
View file @
5e744ff9
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
#ifndef GOOGLE_PROTOBUF_COMPILER_SUBPROCESS_H__
#define GOOGLE_PROTOBUF_COMPILER_SUBPROCESS_H__
#include <vector>
#include <string>
#include <sys/types.h>
#include <unistd.h>
#include <google/protobuf/stubs/common.h>
namespace
google
{
namespace
protobuf
{
class
Message
;
namespace
compiler
{
// Utility class for launching sub-processes.
class
Subprocess
{
public
:
Subprocess
();
~
Subprocess
();
enum
SearchMode
{
SEARCH_PATH
,
// Use PATH environment variable.
EXACT_NAME
// Program is an exact file name; don't use the PATH.
};
// Start the subprocess. Currently we don't provide a way to specify
// arguments as protoc plugins don't have any.
void
Start
(
const
string
&
program
,
SearchMode
search_mode
);
// Serialize the input message and pipe it to the subprocess's stdin, then
// close the pipe. Meanwhile, read from the subprocess's stdout and parse
// the data into *output. All this is done carefully to avoid deadlocks.
// Returns true if successful. On any sort of error, returns false and sets
// *error to a description of the problem.
bool
Communicate
(
const
Message
&
input
,
Message
*
output
,
string
*
error
);
private
:
pid_t
child_pid_
;
// The file descriptors for our end of the child's pipes. We close each and
// set it to -1 when no longer needed.
int
child_stdin_
;
int
child_stdout_
;
};
}
// namespace compiler
}
// namespace protobuf
}
// namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_SUBPROCESS_H__
src/google/protobuf/compiler/test_plugin.cc
0 → 100644
View file @
5e744ff9
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
//
// This is a dummy code generator plugin used by
// command_line_interface_unittest.
#include <string>
#include <google/protobuf/compiler/plugin.h>
#include <google/protobuf/compiler/mock_code_generator.h>
#include <google/protobuf/stubs/strutil.h>
int
main
(
int
argc
,
char
*
argv
[])
{
google
::
protobuf
::
compiler
::
MockCodeGenerator
generator
(
"test_plugin"
);
return
google
::
protobuf
::
compiler
::
PluginMain
(
argc
,
argv
,
&
generator
);
}
src/google/protobuf/io/coded_stream_inl.h
0 → 100644
View file @
5e744ff9
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: jasonh@google.com (Jason Hsueh)
//
// Implements methods of coded_stream.h that need to be inlined for performance
// reasons, but should not be defined in a public header.
#ifndef GOOGLE_PROTOBUF_IO_CODED_STREAM_INL_H__
#define GOOGLE_PROTOBUF_IO_CODED_STREAM_INL_H__
#include <google/protobuf/io/coded_stream.h>
#include <string>
#include <google/protobuf/stubs/stl_util-inl.h>
namespace
google
{
namespace
protobuf
{
namespace
io
{
inline
bool
CodedInputStream
::
InternalReadStringInline
(
string
*
buffer
,
int
size
)
{
if
(
size
<
0
)
return
false
;
// security: size is often user-supplied
if
(
BufferSize
()
>=
size
)
{
STLStringResizeUninitialized
(
buffer
,
size
);
memcpy
(
string_as_array
(
buffer
),
buffer_
,
size
);
Advance
(
size
);
return
true
;
}
return
ReadStringFallback
(
buffer
,
size
);
}
}
// namespace io
}
// namespace protobuf
}
// namespace google
#endif // GOOGLE_PROTOBUF_IO_CODED_STREAM_INL_H__
src/google/protobuf/unittest_no_generic_services.proto
0 → 100644
View file @
5e744ff9
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
package
google
.
protobuf.no_generic_services_test
;
option
cc_generic_services
=
false
;
option
java_generic_services
=
false
;
option
py_generic_services
=
false
;
message
TestMessage
{
optional
int32
a
=
1
;
extensions
1000
to
max
;
}
enum
TestEnum
{
FOO
=
1
;
}
extend
TestMessage
{
optional
int32
test_extension
=
1000
;
}
service
TestService
{
rpc
Foo
(
TestMessage
)
returns
(
TestMessage
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment