1d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// Protocol Buffers - Google's data interchange format
2d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// Copyright 2008 Google Inc.  All rights reserved.
3d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// http://code.google.com/p/protobuf/
4d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville//
5d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// Redistribution and use in source and binary forms, with or without
6d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// modification, are permitted provided that the following conditions are
7d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// met:
8d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville//
9d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville//     * Redistributions of source code must retain the above copyright
10d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// notice, this list of conditions and the following disclaimer.
11d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville//     * Redistributions in binary form must reproduce the above
12d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// copyright notice, this list of conditions and the following disclaimer
13d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// in the documentation and/or other materials provided with the
14d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// distribution.
15d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville//     * Neither the name of Google Inc. nor the names of its
16d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// contributors may be used to endorse or promote products derived from
17d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// this software without specific prior written permission.
18d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville//
19d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
31d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// Author: kenton@google.com (Kenton Varda)
32d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville//
33d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// TODO(kenton):  Share code with the versions of this test in other languages?
34d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville//   It seemed like parameterizing it would add more complexity than it is
35d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville//   worth.
36d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
37d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#include <google/protobuf/compiler/java/java_generator.h>
38d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#include <google/protobuf/compiler/command_line_interface.h>
39d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#include <google/protobuf/io/zero_copy_stream.h>
40d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#include <google/protobuf/io/printer.h>
41d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
42d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#include <google/protobuf/testing/googletest.h>
43d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#include <gtest/gtest.h>
44d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#include <google/protobuf/testing/file.h>
45d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
46d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillenamespace google {
47d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillenamespace protobuf {
48d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillenamespace compiler {
49d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillenamespace java {
50d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savillenamespace {
51d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
52d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Savilleclass TestGenerator : public CodeGenerator {
53d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville public:
54d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  TestGenerator() {}
55d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  ~TestGenerator() {}
56d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
57d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  virtual bool Generate(const FileDescriptor* file,
58d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville                        const string& parameter,
59d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville                        OutputDirectory* output_directory,
60d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville                        string* error) const {
61d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    TryInsert("Test.java", "outer_class_scope", output_directory);
62d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    TryInsert("Test.java", "class_scope:foo.Bar", output_directory);
63d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    TryInsert("Test.java", "class_scope:foo.Bar.Baz", output_directory);
64d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    TryInsert("Test.java", "builder_scope:foo.Bar", output_directory);
65d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    TryInsert("Test.java", "builder_scope:foo.Bar.Baz", output_directory);
66d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    TryInsert("Test.java", "enum_scope:foo.Qux", output_directory);
67d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    return true;
68d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  }
69d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
70d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  void TryInsert(const string& filename, const string& insertion_point,
71d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville                 OutputDirectory* output_directory) const {
72d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    scoped_ptr<io::ZeroCopyOutputStream> output(
73d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      output_directory->OpenForInsert(filename, insertion_point));
74d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    io::Printer printer(output.get(), '$');
75d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    printer.Print("// inserted $name$\n", "name", insertion_point);
76d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  }
77d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville};
78d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
79d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// This test verifies that all the expected insertion points exist.  It does
80d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// not verify that they are correctly-placed; that would require actually
81d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville// compiling the output which is a bit more than I care to do for this test.
82d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink SavilleTEST(JavaPluginTest, PluginTest) {
83d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  File::WriteStringToFileOrDie(
84d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "syntax = \"proto2\";\n"
85d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "package foo;\n"
86d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "option java_package = \"\";\n"
87d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "option java_outer_classname = \"Test\";\n"
88d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "message Bar {\n"
89d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "  message Baz {}\n"
90d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "}\n"
91d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      "enum Qux { BLAH = 1; }\n",
92d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville      TestTempDir() + "/test.proto");
93d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
94d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  google::protobuf::compiler::CommandLineInterface cli;
95d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  cli.SetInputsAreProtoPathRelative(true);
96d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
97d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  JavaGenerator java_generator;
98d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  TestGenerator test_generator;
99d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  cli.RegisterGenerator("--java_out", &java_generator, "");
100d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  cli.RegisterGenerator("--test_out", &test_generator, "");
101d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
102d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  string proto_path = "-I" + TestTempDir();
103d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  string java_out = "--java_out=" + TestTempDir();
104d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  string test_out = "--test_out=" + TestTempDir();
105d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
106d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  const char* argv[] = {
107d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "protoc",
108d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    proto_path.c_str(),
109d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    java_out.c_str(),
110d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    test_out.c_str(),
111d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville    "test.proto"
112d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  };
113d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
114d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville  EXPECT_EQ(0, cli.Run(5, argv));
115d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville}
116d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville
117d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville}  // namespace
118d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville}  // namespace java
119d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville}  // namespace compiler
120d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville}  // namespace protobuf
121d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville}  // namespace google
122