OLD | NEW |
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 // https://developers.google.com/protocol-buffers/ | 3 // https://developers.google.com/protocol-buffers/ |
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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 #include <google/protobuf/descriptor.h> | 50 #include <google/protobuf/descriptor.h> |
51 #include <google/protobuf/io/zero_copy_stream.h> | 51 #include <google/protobuf/io/zero_copy_stream.h> |
52 #include <google/protobuf/compiler/command_line_interface.h> | 52 #include <google/protobuf/compiler/command_line_interface.h> |
53 #include <google/protobuf/compiler/code_generator.h> | 53 #include <google/protobuf/compiler/code_generator.h> |
54 #include <google/protobuf/testing/file.h> | 54 #include <google/protobuf/testing/file.h> |
55 #include <google/protobuf/compiler/mock_code_generator.h> | 55 #include <google/protobuf/compiler/mock_code_generator.h> |
56 #include <google/protobuf/compiler/subprocess.h> | 56 #include <google/protobuf/compiler/subprocess.h> |
57 #include <google/protobuf/io/printer.h> | 57 #include <google/protobuf/io/printer.h> |
58 #include <google/protobuf/unittest.pb.h> | 58 #include <google/protobuf/unittest.pb.h> |
59 #include <google/protobuf/testing/file.h> | 59 #include <google/protobuf/testing/file.h> |
60 #include <google/protobuf/stubs/stringprintf.h> | |
61 #include <google/protobuf/stubs/strutil.h> | 60 #include <google/protobuf/stubs/strutil.h> |
62 #include <google/protobuf/stubs/substitute.h> | 61 #include <google/protobuf/stubs/substitute.h> |
63 | 62 |
64 #include <google/protobuf/testing/file.h> | 63 #include <google/protobuf/testing/file.h> |
65 #include <google/protobuf/testing/googletest.h> | 64 #include <google/protobuf/testing/googletest.h> |
66 #include <gtest/gtest.h> | 65 #include <gtest/gtest.h> |
67 | 66 |
68 | 67 |
69 namespace google { | 68 namespace google { |
70 namespace protobuf { | 69 namespace protobuf { |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 // The result of Run(). | 210 // The result of Run(). |
212 int return_code_; | 211 int return_code_; |
213 | 212 |
214 // The captured stderr output. | 213 // The captured stderr output. |
215 string error_text_; | 214 string error_text_; |
216 | 215 |
217 // The captured stdout. | 216 // The captured stdout. |
218 string captured_stdout_; | 217 string captured_stdout_; |
219 | 218 |
220 // Pointers which need to be deleted later. | 219 // Pointers which need to be deleted later. |
221 std::vector<CodeGenerator*> mock_generators_to_delete_; | 220 vector<CodeGenerator*> mock_generators_to_delete_; |
222 | 221 |
223 NullCodeGenerator* null_generator_; | 222 NullCodeGenerator* null_generator_; |
224 }; | 223 }; |
225 | 224 |
226 class CommandLineInterfaceTest::NullCodeGenerator : public CodeGenerator { | 225 class CommandLineInterfaceTest::NullCodeGenerator : public CodeGenerator { |
227 public: | 226 public: |
228 NullCodeGenerator() : called_(false) {} | 227 NullCodeGenerator() : called_(false) {} |
229 ~NullCodeGenerator() {} | 228 ~NullCodeGenerator() {} |
230 | 229 |
231 mutable bool called_; | 230 mutable bool called_; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 } | 284 } |
286 | 285 |
287 // Delete all the MockCodeGenerators. | 286 // Delete all the MockCodeGenerators. |
288 for (int i = 0; i < mock_generators_to_delete_.size(); i++) { | 287 for (int i = 0; i < mock_generators_to_delete_.size(); i++) { |
289 delete mock_generators_to_delete_[i]; | 288 delete mock_generators_to_delete_[i]; |
290 } | 289 } |
291 mock_generators_to_delete_.clear(); | 290 mock_generators_to_delete_.clear(); |
292 } | 291 } |
293 | 292 |
294 void CommandLineInterfaceTest::Run(const string& command) { | 293 void CommandLineInterfaceTest::Run(const string& command) { |
295 std::vector<string> args = Split(command, " ", true); | 294 vector<string> args = Split(command, " ", true); |
296 | 295 |
297 if (!disallow_plugins_) { | 296 if (!disallow_plugins_) { |
298 cli_.AllowPlugins("prefix-"); | 297 cli_.AllowPlugins("prefix-"); |
299 #ifndef GOOGLE_THIRD_PARTY_PROTOBUF | 298 #ifndef GOOGLE_THIRD_PARTY_PROTOBUF |
300 string plugin_path; | 299 string plugin_path; |
301 #ifdef GOOGLE_PROTOBUF_TEST_PLUGIN_PATH | 300 #ifdef GOOGLE_PROTOBUF_TEST_PLUGIN_PATH |
302 plugin_path = GOOGLE_PROTOBUF_TEST_PLUGIN_PATH; | 301 plugin_path = GOOGLE_PROTOBUF_TEST_PLUGIN_PATH; |
303 #else | 302 #else |
304 const char* possible_paths[] = { | 303 const char* possible_paths[] = { |
305 // When building with shared libraries, libtool hides the real executable | 304 // When building with shared libraries, libtool hides the real executable |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
647 "--test_opt=foo3 " | 646 "--test_opt=foo3 " |
648 "--proto_path=$tmpdir foo.proto"); | 647 "--proto_path=$tmpdir foo.proto"); |
649 | 648 |
650 ExpectNoErrors(); | 649 ExpectNoErrors(); |
651 ExpectGenerated( | 650 ExpectGenerated( |
652 "test_generator", "bar,foo1,foo2,foo3", "foo.proto", "Foo", "a"); | 651 "test_generator", "bar,foo1,foo2,foo3", "foo.proto", "Foo", "a"); |
653 ExpectGenerated( | 652 ExpectGenerated( |
654 "test_generator", "baz,foo1,foo2,foo3", "foo.proto", "Foo", "b"); | 653 "test_generator", "baz,foo1,foo2,foo3", "foo.proto", "Foo", "b"); |
655 } | 654 } |
656 | 655 |
657 TEST_F(CommandLineInterfaceTest, ExtraPluginParameters) { | |
658 // Test that generator parameters specified with the option flag are | |
659 // correctly passed to the code generator. | |
660 | |
661 CreateTempFile("foo.proto", | |
662 "syntax = \"proto2\";\n" | |
663 "message Foo {}\n"); | |
664 // Create the "a" and "b" sub-directories. | |
665 CreateTempDir("a"); | |
666 CreateTempDir("b"); | |
667 | |
668 Run("protocol_compiler " | |
669 "--plug_opt=foo1 " | |
670 "--plug_out=bar:$tmpdir/a " | |
671 "--plug_opt=foo2 " | |
672 "--plug_out=baz:$tmpdir/b " | |
673 "--plug_opt=foo3 " | |
674 "--proto_path=$tmpdir foo.proto"); | |
675 | |
676 ExpectNoErrors(); | |
677 ExpectGenerated( | |
678 "test_plugin", "bar,foo1,foo2,foo3", "foo.proto", "Foo", "a"); | |
679 ExpectGenerated( | |
680 "test_plugin", "baz,foo1,foo2,foo3", "foo.proto", "Foo", "b"); | |
681 } | |
682 | |
683 TEST_F(CommandLineInterfaceTest, UnrecognizedExtraParameters) { | |
684 CreateTempFile("foo.proto", | |
685 "syntax = \"proto2\";\n" | |
686 "message Foo {}\n"); | |
687 | |
688 Run("protocol_compiler --plug_out=TestParameter:$tmpdir " | |
689 "--unknown_plug_opt=Foo " | |
690 "--proto_path=$tmpdir foo.proto"); | |
691 | |
692 ExpectErrorSubstring("Unknown flag: --unknown_plug_opt"); | |
693 } | |
694 | |
695 TEST_F(CommandLineInterfaceTest, Insert) { | 656 TEST_F(CommandLineInterfaceTest, Insert) { |
696 // Test running a generator that inserts code into another's output. | 657 // Test running a generator that inserts code into another's output. |
697 | 658 |
698 CreateTempFile("foo.proto", | 659 CreateTempFile("foo.proto", |
699 "syntax = \"proto2\";\n" | 660 "syntax = \"proto2\";\n" |
700 "message Foo {}\n"); | 661 "message Foo {}\n"); |
701 | 662 |
702 Run("protocol_compiler " | 663 Run("protocol_compiler " |
703 "--test_out=TestParameter:$tmpdir " | 664 "--test_out=TestParameter:$tmpdir " |
704 "--plug_out=TestPluginParameter:$tmpdir " | 665 "--plug_out=TestPluginParameter:$tmpdir " |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
751 "syntax = \"proto2\";\n" | 712 "syntax = \"proto2\";\n" |
752 "message Foo {}\n"); | 713 "message Foo {}\n"); |
753 | 714 |
754 Run("protocol_compiler --test_out=$tmpdir\\ " | 715 Run("protocol_compiler --test_out=$tmpdir\\ " |
755 "--proto_path=$tmpdir\\ foo.proto"); | 716 "--proto_path=$tmpdir\\ foo.proto"); |
756 | 717 |
757 ExpectNoErrors(); | 718 ExpectNoErrors(); |
758 ExpectGenerated("test_generator", "", "foo.proto", "Foo"); | 719 ExpectGenerated("test_generator", "", "foo.proto", "Foo"); |
759 } | 720 } |
760 | 721 |
761 TEST_F(CommandLineInterfaceTest, Win32ErrorMessage) { | |
762 EXPECT_EQ("The system cannot find the file specified.\r\n", | |
763 Subprocess::Win32ErrorMessage(ERROR_FILE_NOT_FOUND)); | |
764 } | |
765 | |
766 #endif // defined(_WIN32) || defined(__CYGWIN__) | 722 #endif // defined(_WIN32) || defined(__CYGWIN__) |
767 | 723 |
768 TEST_F(CommandLineInterfaceTest, PathLookup) { | 724 TEST_F(CommandLineInterfaceTest, PathLookup) { |
769 // Test that specifying multiple directories in the proto search path works. | 725 // Test that specifying multiple directories in the proto search path works. |
770 | 726 |
771 CreateTempFile("b/bar.proto", | 727 CreateTempFile("b/bar.proto", |
772 "syntax = \"proto2\";\n" | 728 "syntax = \"proto2\";\n" |
773 "message Bar {}\n"); | 729 "message Bar {}\n"); |
774 CreateTempFile("a/foo.proto", | 730 CreateTempFile("a/foo.proto", |
775 "syntax = \"proto2\";\n" | 731 "syntax = \"proto2\";\n" |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
823 "syntax = \"proto2\";\n" | 779 "syntax = \"proto2\";\n" |
824 "message Foo {}\n"); | 780 "message Foo {}\n"); |
825 | 781 |
826 Run("protocol_compiler --test_out=$tmpdir " | 782 Run("protocol_compiler --test_out=$tmpdir " |
827 "--proto_path=bar=$tmpdir bar/foo.proto"); | 783 "--proto_path=bar=$tmpdir bar/foo.proto"); |
828 | 784 |
829 ExpectNoErrors(); | 785 ExpectNoErrors(); |
830 ExpectGenerated("test_generator", "", "bar/foo.proto", "Foo"); | 786 ExpectGenerated("test_generator", "", "bar/foo.proto", "Foo"); |
831 } | 787 } |
832 | 788 |
833 TEST_F(CommandLineInterfaceTest, PathWithEqualsSign) { | |
834 // Test setting up a search path which happens to have '=' in it. | |
835 | |
836 CreateTempDir("with=sign"); | |
837 CreateTempFile("with=sign/foo.proto", | |
838 "syntax = \"proto2\";\n" | |
839 "message Foo {}\n"); | |
840 | |
841 Run("protocol_compiler --test_out=$tmpdir " | |
842 "--proto_path=$tmpdir/with=sign foo.proto"); | |
843 | |
844 ExpectNoErrors(); | |
845 ExpectGenerated("test_generator", "", "foo.proto", "Foo"); | |
846 } | |
847 | |
848 TEST_F(CommandLineInterfaceTest, MultipleGenerators) { | 789 TEST_F(CommandLineInterfaceTest, MultipleGenerators) { |
849 // Test that we can have multiple generators and use both in one invocation, | 790 // Test that we can have multiple generators and use both in one invocation, |
850 // each with a different output directory. | 791 // each with a different output directory. |
851 | 792 |
852 CreateTempFile("foo.proto", | 793 CreateTempFile("foo.proto", |
853 "syntax = \"proto2\";\n" | 794 "syntax = \"proto2\";\n" |
854 "message Foo {}\n"); | 795 "message Foo {}\n"); |
855 // Create the "a" and "b" sub-directories. | 796 // Create the "a" and "b" sub-directories. |
856 CreateTempDir("a"); | 797 CreateTempDir("a"); |
857 CreateTempDir("b"); | 798 CreateTempDir("b"); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
903 "message Foo {}\n" | 844 "message Foo {}\n" |
904 "service Bar {}\n"); | 845 "service Bar {}\n"); |
905 | 846 |
906 Run("protocol_compiler --test_out=$tmpdir " | 847 Run("protocol_compiler --test_out=$tmpdir " |
907 "--proto_path=$tmpdir foo.proto"); | 848 "--proto_path=$tmpdir foo.proto"); |
908 | 849 |
909 ExpectNoErrors(); | 850 ExpectNoErrors(); |
910 ExpectGenerated("test_generator", "", "foo.proto", "Foo"); | 851 ExpectGenerated("test_generator", "", "foo.proto", "Foo"); |
911 } | 852 } |
912 | 853 |
913 TEST_F(CommandLineInterfaceTest, DirectDependencies_Missing_EmptyList) { | |
914 CreateTempFile("foo.proto", | |
915 "syntax = \"proto2\";\n" | |
916 "import \"bar.proto\";\n" | |
917 "message Foo { optional Bar bar = 1; }"); | |
918 CreateTempFile("bar.proto", | |
919 "syntax = \"proto2\";\n" | |
920 "message Bar { optional string text = 1; }"); | |
921 | |
922 Run("protocol_compiler --test_out=$tmpdir --proto_path=$tmpdir " | |
923 "--direct_dependencies= foo.proto"); | |
924 | |
925 ExpectErrorText( | |
926 "foo.proto: File is imported but not declared in --direct_dependencies: " | |
927 "bar.proto\n"); | |
928 } | |
929 | |
930 TEST_F(CommandLineInterfaceTest, DirectDependencies_Missing) { | |
931 CreateTempFile("foo.proto", | |
932 "syntax = \"proto2\";\n" | |
933 "import \"bar.proto\";\n" | |
934 "import \"bla.proto\";\n" | |
935 "message Foo { optional Bar bar = 1; optional Bla bla = 2; }"); | |
936 CreateTempFile("bar.proto", | |
937 "syntax = \"proto2\";\n" | |
938 "message Bar { optional string text = 1; }"); | |
939 CreateTempFile("bla.proto", | |
940 "syntax = \"proto2\";\n" | |
941 "message Bla { optional int64 number = 1; }"); | |
942 | |
943 Run("protocol_compiler --test_out=$tmpdir --proto_path=$tmpdir " | |
944 "--direct_dependencies=bla.proto foo.proto"); | |
945 | |
946 ExpectErrorText( | |
947 "foo.proto: File is imported but not declared in --direct_dependencies: " | |
948 "bar.proto\n"); | |
949 } | |
950 | |
951 TEST_F(CommandLineInterfaceTest, DirectDependencies_NoViolation) { | |
952 CreateTempFile("foo.proto", | |
953 "syntax = \"proto2\";\n" | |
954 "import \"bar.proto\";\n" | |
955 "message Foo { optional Bar bar = 1; }"); | |
956 CreateTempFile("bar.proto", | |
957 "syntax = \"proto2\";\n" | |
958 "message Bar { optional string text = 1; }"); | |
959 | |
960 Run("protocol_compiler --test_out=$tmpdir --proto_path=$tmpdir " | |
961 "--direct_dependencies=bar.proto foo.proto"); | |
962 | |
963 ExpectNoErrors(); | |
964 } | |
965 | |
966 TEST_F(CommandLineInterfaceTest, DirectDependencies_NoViolation_MultiImports) { | |
967 CreateTempFile("foo.proto", | |
968 "syntax = \"proto2\";\n" | |
969 "import \"bar.proto\";\n" | |
970 "import \"bla.proto\";\n" | |
971 "message Foo { optional Bar bar = 1; optional Bla bla = 2; }"); | |
972 CreateTempFile("bar.proto", | |
973 "syntax = \"proto2\";\n" | |
974 "message Bar { optional string text = 1; }"); | |
975 CreateTempFile("bla.proto", | |
976 "syntax = \"proto2\";\n" | |
977 "message Bla { optional int64 number = 1; }"); | |
978 | |
979 Run("protocol_compiler --test_out=$tmpdir --proto_path=$tmpdir " | |
980 "--direct_dependencies=bar.proto:bla.proto foo.proto"); | |
981 | |
982 ExpectNoErrors(); | |
983 } | |
984 | |
985 TEST_F(CommandLineInterfaceTest, DirectDependencies_ProvidedMultipleTimes) { | |
986 CreateTempFile("foo.proto", | |
987 "syntax = \"proto2\";\n"); | |
988 | |
989 Run("protocol_compiler --test_out=$tmpdir --proto_path=$tmpdir " | |
990 "--direct_dependencies=bar.proto --direct_dependencies=bla.proto " | |
991 "foo.proto"); | |
992 | |
993 ExpectErrorText( | |
994 "--direct_dependencies may only be passed once. To specify multiple " | |
995 "direct dependencies, pass them all as a single parameter separated by " | |
996 "':'.\n"); | |
997 } | |
998 | |
999 TEST_F(CommandLineInterfaceTest, CwdRelativeInputs) { | 854 TEST_F(CommandLineInterfaceTest, CwdRelativeInputs) { |
1000 // Test that we can accept working-directory-relative input files. | 855 // Test that we can accept working-directory-relative input files. |
1001 | 856 |
1002 SetInputsAreProtoPathRelative(false); | 857 SetInputsAreProtoPathRelative(false); |
1003 | 858 |
1004 CreateTempFile("foo.proto", | 859 CreateTempFile("foo.proto", |
1005 "syntax = \"proto2\";\n" | 860 "syntax = \"proto2\";\n" |
1006 "message Foo {}\n"); | 861 "message Foo {}\n"); |
1007 | 862 |
1008 Run("protocol_compiler --test_out=$tmpdir " | 863 Run("protocol_compiler --test_out=$tmpdir " |
(...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1576 "syntax = \"proto2\";\n" | 1431 "syntax = \"proto2\";\n" |
1577 "message MockCodeGenerator_HasJsonName {\n" | 1432 "message MockCodeGenerator_HasJsonName {\n" |
1578 " optional int32 value = 1;\n" | 1433 " optional int32 value = 1;\n" |
1579 "}\n"); | 1434 "}\n"); |
1580 | 1435 |
1581 Run("protocol_compiler --plug_out=$tmpdir --proto_path=$tmpdir foo.proto"); | 1436 Run("protocol_compiler --plug_out=$tmpdir --proto_path=$tmpdir foo.proto"); |
1582 | 1437 |
1583 ExpectErrorSubstring("Saw json_name: 1"); | 1438 ExpectErrorSubstring("Saw json_name: 1"); |
1584 } | 1439 } |
1585 | 1440 |
1586 TEST_F(CommandLineInterfaceTest, PluginReceivesCompilerVersion) { | |
1587 CreateTempFile("foo.proto", | |
1588 "syntax = \"proto2\";\n" | |
1589 "message MockCodeGenerator_ShowVersionNumber {\n" | |
1590 " optional int32 value = 1;\n" | |
1591 "}\n"); | |
1592 | |
1593 Run("protocol_compiler --plug_out=$tmpdir --proto_path=$tmpdir foo.proto"); | |
1594 | |
1595 ExpectErrorSubstring( | |
1596 StringPrintf("Saw compiler_version: %d %s", | |
1597 GOOGLE_PROTOBUF_VERSION, | |
1598 GOOGLE_PROTOBUF_VERSION_SUFFIX)); | |
1599 } | |
1600 | |
1601 TEST_F(CommandLineInterfaceTest, GeneratorPluginNotFound) { | 1441 TEST_F(CommandLineInterfaceTest, GeneratorPluginNotFound) { |
1602 // Test what happens if the plugin isn't found. | 1442 // Test what happens if the plugin isn't found. |
1603 | 1443 |
1604 CreateTempFile("error.proto", | 1444 CreateTempFile("error.proto", |
1605 "syntax = \"proto2\";\n" | 1445 "syntax = \"proto2\";\n" |
1606 "message Foo {}\n"); | 1446 "message Foo {}\n"); |
1607 | 1447 |
1608 Run("protocol_compiler --badplug_out=TestParameter:$tmpdir " | 1448 Run("protocol_compiler --badplug_out=TestParameter:$tmpdir " |
1609 "--plugin=prefix-gen-badplug=no_such_file " | 1449 "--plugin=prefix-gen-badplug=no_such_file " |
1610 "--proto_path=$tmpdir error.proto"); | 1450 "--proto_path=$tmpdir error.proto"); |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1865 } | 1705 } |
1866 } | 1706 } |
1867 | 1707 |
1868 return result; | 1708 return result; |
1869 } | 1709 } |
1870 | 1710 |
1871 enum Type { TEXT, BINARY }; | 1711 enum Type { TEXT, BINARY }; |
1872 enum ReturnCode { SUCCESS, ERROR }; | 1712 enum ReturnCode { SUCCESS, ERROR }; |
1873 | 1713 |
1874 bool Run(const string& command) { | 1714 bool Run(const string& command) { |
1875 std::vector<string> args; | 1715 vector<string> args; |
1876 args.push_back("protoc"); | 1716 args.push_back("protoc"); |
1877 SplitStringUsing(command, " ", &args); | 1717 SplitStringUsing(command, " ", &args); |
1878 args.push_back("--proto_path=" + TestSourceDir()); | 1718 args.push_back("--proto_path=" + TestSourceDir()); |
1879 | 1719 |
1880 google::protobuf::scoped_array<const char * > argv(new const char* [args.siz
e()]); | 1720 google::protobuf::scoped_array<const char * > argv(new const char* [args.siz
e()]); |
1881 for (int i = 0; i < args.size(); i++) { | 1721 for (int i = 0; i < args.size(); i++) { |
1882 argv[i] = args[i].c_str(); | 1722 argv[i] = args[i].c_str(); |
1883 } | 1723 } |
1884 | 1724 |
1885 CommandLineInterface cli; | 1725 CommandLineInterface cli; |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1985 "google/protobuf/no_such_file.proto: File not found.\n"); | 1825 "google/protobuf/no_such_file.proto: File not found.\n"); |
1986 } | 1826 } |
1987 | 1827 |
1988 } // anonymous namespace | 1828 } // anonymous namespace |
1989 | 1829 |
1990 #endif // !GOOGLE_PROTOBUF_HEAP_CHECK_DRACONIAN | 1830 #endif // !GOOGLE_PROTOBUF_HEAP_CHECK_DRACONIAN |
1991 | 1831 |
1992 } // namespace compiler | 1832 } // namespace compiler |
1993 } // namespace protobuf | 1833 } // namespace protobuf |
1994 } // namespace google | 1834 } // namespace google |
OLD | NEW |