diff options
Diffstat (limited to 'NorthstarDedicatedTest/include/protobuf/compiler/java')
62 files changed, 23138 insertions, 0 deletions
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_context.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_context.cc new file mode 100644 index 00000000..00ffc946 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_context.cc @@ -0,0 +1,202 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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. + +#include <compiler/java/java_context.h> + +#include <compiler/java/java_field.h> +#include <compiler/java/java_helpers.h> +#include <compiler/java/java_name_resolver.h> +#include <descriptor.h> +#include <stubs/strutil.h> +#include <stubs/map_util.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +Context::Context(const FileDescriptor* file, const Options& options) + : name_resolver_(new ClassNameResolver), options_(options) { + InitializeFieldGeneratorInfo(file); +} + +Context::~Context() {} + +ClassNameResolver* Context::GetNameResolver() const { + return name_resolver_.get(); +} + +namespace { +// Whether two fields have conflicting accessors (assuming name1 and name2 +// are different). name1 and name2 are field1 and field2's camel-case name +// respectively. +bool IsConflicting(const FieldDescriptor* field1, const std::string& name1, + const FieldDescriptor* field2, const std::string& name2, + std::string* info) { + if (field1->is_repeated()) { + if (field2->is_repeated()) { + // Both fields are repeated. + return false; + } else { + // field1 is repeated, and field2 is not. + if (name1 + "Count" == name2) { + *info = "both repeated field \"" + field1->name() + "\" and singular " + + "field \"" + field2->name() + "\" generate the method \"" + + "get" + name1 + "Count()\""; + return true; + } + if (name1 + "List" == name2) { + *info = "both repeated field \"" + field1->name() + "\" and singular " + + "field \"" + field2->name() + "\" generate the method \"" + + "get" + name1 + "List()\""; + return true; + } + // Well, there are obviously many more conflicting cases, but it probably + // doesn't worth the effort to exhaust all of them because they rarely + // happen and as we are continuing adding new methods/changing existing + // methods the number of different conflicting cases will keep growing. + // We can just add more cases here when they are found in the real world. + return false; + } + } else { + if (field2->is_repeated()) { + return IsConflicting(field2, name2, field1, name1, info); + } else { + // None of the two fields are repeated. + return false; + } + } +} +} // namespace + +void Context::InitializeFieldGeneratorInfo(const FileDescriptor* file) { + for (int i = 0; i < file->message_type_count(); ++i) { + InitializeFieldGeneratorInfoForMessage(file->message_type(i)); + } +} + +void Context::InitializeFieldGeneratorInfoForMessage( + const Descriptor* message) { + for (int i = 0; i < message->nested_type_count(); ++i) { + InitializeFieldGeneratorInfoForMessage(message->nested_type(i)); + } + std::vector<const FieldDescriptor*> fields; + fields.reserve(message->field_count()); + for (int i = 0; i < message->field_count(); ++i) { + fields.push_back(message->field(i)); + } + InitializeFieldGeneratorInfoForFields(fields); + + for (int i = 0; i < message->oneof_decl_count(); ++i) { + const OneofDescriptor* oneof = message->oneof_decl(i); + OneofGeneratorInfo info; + info.name = UnderscoresToCamelCase(oneof->name(), false); + info.capitalized_name = UnderscoresToCamelCase(oneof->name(), true); + oneof_generator_info_map_[oneof] = info; + } +} + +void Context::InitializeFieldGeneratorInfoForFields( + const std::vector<const FieldDescriptor*>& fields) { + // Find out all fields that conflict with some other field in the same + // message. + std::vector<bool> is_conflict(fields.size()); + std::vector<std::string> conflict_reason(fields.size()); + for (int i = 0; i < fields.size(); ++i) { + const FieldDescriptor* field = fields[i]; + const std::string& name = UnderscoresToCapitalizedCamelCase(field); + for (int j = i + 1; j < fields.size(); ++j) { + const FieldDescriptor* other = fields[j]; + const std::string& other_name = UnderscoresToCapitalizedCamelCase(other); + if (name == other_name) { + is_conflict[i] = is_conflict[j] = true; + conflict_reason[i] = conflict_reason[j] = + "capitalized name of field \"" + field->name() + + "\" conflicts with field \"" + other->name() + "\""; + } else if (IsConflicting(field, name, other, other_name, + &conflict_reason[j])) { + is_conflict[i] = is_conflict[j] = true; + conflict_reason[i] = conflict_reason[j]; + } + } + if (is_conflict[i]) { + GOOGLE_LOG(WARNING) << "field \"" << field->full_name() << "\" is conflicting " + << "with another field: " << conflict_reason[i]; + } + } + for (int i = 0; i < fields.size(); ++i) { + const FieldDescriptor* field = fields[i]; + FieldGeneratorInfo info; + info.name = CamelCaseFieldName(field); + info.capitalized_name = UnderscoresToCapitalizedCamelCase(field); + // For fields conflicting with some other fields, we append the field + // number to their field names in generated code to avoid conflicts. + if (is_conflict[i]) { + info.name += StrCat(field->number()); + info.capitalized_name += StrCat(field->number()); + info.disambiguated_reason = conflict_reason[i]; + } + field_generator_info_map_[field] = info; + } +} + +const FieldGeneratorInfo* Context::GetFieldGeneratorInfo( + const FieldDescriptor* field) const { + const FieldGeneratorInfo* result = + FindOrNull(field_generator_info_map_, field); + if (result == NULL) { + GOOGLE_LOG(FATAL) << "Can not find FieldGeneratorInfo for field: " + << field->full_name(); + } + return result; +} + +const OneofGeneratorInfo* Context::GetOneofGeneratorInfo( + const OneofDescriptor* oneof) const { + const OneofGeneratorInfo* result = + FindOrNull(oneof_generator_info_map_, oneof); + if (result == NULL) { + GOOGLE_LOG(FATAL) << "Can not find OneofGeneratorInfo for oneof: " + << oneof->name(); + } + return result; +} + +// Does this message class have generated parsing, serialization, and other +// standard methods for which reflection-based fallback implementations exist? +bool Context::HasGeneratedMethods(const Descriptor* descriptor) const { + return options_.enforce_lite || + descriptor->file()->options().optimize_for() != FileOptions::CODE_SIZE; +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_context.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_context.h new file mode 100644 index 00000000..ed6e9e9c --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_context.h @@ -0,0 +1,113 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_CONTEXT_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_CONTEXT_H__ + +#include <map> +#include <memory> +#include <vector> + +#include <stubs/common.h> +#include <compiler/java/java_options.h> + +namespace google { +namespace protobuf { +class FileDescriptor; +class FieldDescriptor; +class OneofDescriptor; +class Descriptor; +class EnumDescriptor; +namespace compiler { +namespace java { +class ClassNameResolver; // name_resolver.h +} +} // namespace compiler +} // namespace protobuf +} // namespace google + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +struct FieldGeneratorInfo; +struct OneofGeneratorInfo; +// A context object holds the information that is shared among all code +// generators. +class Context { + public: + Context(const FileDescriptor* file, const Options& options); + ~Context(); + + // Get the name resolver associated with this context. The resolver + // can be used to map descriptors to Java class names. + ClassNameResolver* GetNameResolver() const; + + // Get the FieldGeneratorInfo for a given field. + const FieldGeneratorInfo* GetFieldGeneratorInfo( + const FieldDescriptor* field) const; + + // Get the OneofGeneratorInfo for a given oneof. + const OneofGeneratorInfo* GetOneofGeneratorInfo( + const OneofDescriptor* oneof) const; + + const Options& options() const { return options_; } + + // Enforces all the files (including transitive dependencies) to use + // LiteRuntime. + + bool EnforceLite() const { return options_.enforce_lite; } + + // Does this message class have generated parsing, serialization, and other + // standard methods for which reflection-based fallback implementations exist? + bool HasGeneratedMethods(const Descriptor* descriptor) const; + + private: + void InitializeFieldGeneratorInfo(const FileDescriptor* file); + void InitializeFieldGeneratorInfoForMessage(const Descriptor* message); + void InitializeFieldGeneratorInfoForFields( + const std::vector<const FieldDescriptor*>& fields); + + std::unique_ptr<ClassNameResolver> name_resolver_; + std::map<const FieldDescriptor*, FieldGeneratorInfo> + field_generator_info_map_; + std::map<const OneofDescriptor*, OneofGeneratorInfo> + oneof_generator_info_map_; + Options options_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Context); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_CONTEXT_H__ diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_doc_comment.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_doc_comment.cc new file mode 100644 index 00000000..ed9f0d27 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_doc_comment.cc @@ -0,0 +1,435 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <compiler/java/java_doc_comment.h> + +#include <vector> + +#include <descriptor.pb.h> +#include <io/printer.h> +#include <stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +std::string EscapeJavadoc(const std::string& input) { + std::string result; + result.reserve(input.size() * 2); + + char prev = '*'; + + for (std::string::size_type i = 0; i < input.size(); i++) { + char c = input[i]; + switch (c) { + case '*': + // Avoid "/*". + if (prev == '/') { + result.append("*"); + } else { + result.push_back(c); + } + break; + case '/': + // Avoid "*/". + if (prev == '*') { + result.append("/"); + } else { + result.push_back(c); + } + break; + case '@': + // '@' starts javadoc tags including the @deprecated tag, which will + // cause a compile-time error if inserted before a declaration that + // does not have a corresponding @Deprecated annotation. + result.append("@"); + break; + case '<': + // Avoid interpretation as HTML. + result.append("<"); + break; + case '>': + // Avoid interpretation as HTML. + result.append(">"); + break; + case '&': + // Avoid interpretation as HTML. + result.append("&"); + break; + case '\\': + // Java interprets Unicode escape sequences anywhere! + result.append("\"); + break; + default: + result.push_back(c); + break; + } + + prev = c; + } + + return result; +} + +static void WriteDocCommentBodyForLocation(io::Printer* printer, + const SourceLocation& location) { + std::string comments = location.leading_comments.empty() + ? location.trailing_comments + : location.leading_comments; + if (!comments.empty()) { + // TODO(kenton): Ideally we should parse the comment text as Markdown and + // write it back as HTML, but this requires a Markdown parser. For now + // we just use <pre> to get fixed-width text formatting. + + // If the comment itself contains block comment start or end markers, + // HTML-escape them so that they don't accidentally close the doc comment. + comments = EscapeJavadoc(comments); + + std::vector<std::string> lines = Split(comments, "\n"); + while (!lines.empty() && lines.back().empty()) { + lines.pop_back(); + } + + printer->Print(" * <pre>\n"); + for (int i = 0; i < lines.size(); i++) { + // Most lines should start with a space. Watch out for lines that start + // with a /, since putting that right after the leading asterisk will + // close the comment. + if (!lines[i].empty() && lines[i][0] == '/') { + printer->Print(" * $line$\n", "line", lines[i]); + } else { + printer->Print(" *$line$\n", "line", lines[i]); + } + } + printer->Print( + " * </pre>\n" + " *\n"); + } +} + +template <typename DescriptorType> +static void WriteDocCommentBody(io::Printer* printer, + const DescriptorType* descriptor) { + SourceLocation location; + if (descriptor->GetSourceLocation(&location)) { + WriteDocCommentBodyForLocation(printer, location); + } +} + +static std::string FirstLineOf(const std::string& value) { + std::string result = value; + + std::string::size_type pos = result.find_first_of('\n'); + if (pos != std::string::npos) { + result.erase(pos); + } + + // If line ends in an opening brace, make it "{ ... }" so it looks nice. + if (!result.empty() && result[result.size() - 1] == '{') { + result.append(" ... }"); + } + + return result; +} + +void WriteMessageDocComment(io::Printer* printer, const Descriptor* message) { + printer->Print("/**\n"); + WriteDocCommentBody(printer, message); + printer->Print( + " * Protobuf type {@code $fullname$}\n" + " */\n", + "fullname", EscapeJavadoc(message->full_name())); +} + +void WriteFieldDocComment(io::Printer* printer, const FieldDescriptor* field) { + // We start the comment with the main body based on the comments from the + // .proto file (if present). We then continue with the field declaration, + // e.g.: + // optional string foo = 5; + // And then we end with the javadoc tags if applicable. + // If the field is a group, the debug string might end with {. + printer->Print("/**\n"); + WriteDocCommentBody(printer, field); + printer->Print(" * <code>$def$</code>\n", "def", + EscapeJavadoc(FirstLineOf(field->DebugString()))); + printer->Print(" */\n"); +} + +void WriteDeprecatedJavadoc(io::Printer* printer, const FieldDescriptor* field, + const FieldAccessorType type) { + if (!field->options().deprecated()) { + return; + } + + // Lite codegen does not annotate set & clear methods with @Deprecated. + if (field->file()->options().optimize_for() == FileOptions::LITE_RUNTIME && + (type == SETTER || type == CLEARER)) { + return; + } + + printer->Print(" * @deprecated\n"); +} + +void WriteFieldAccessorDocComment(io::Printer* printer, + const FieldDescriptor* field, + const FieldAccessorType type, + const bool builder) { + printer->Print("/**\n"); + WriteDocCommentBody(printer, field); + printer->Print(" * <code>$def$</code>\n", "def", + EscapeJavadoc(FirstLineOf(field->DebugString()))); + WriteDeprecatedJavadoc(printer, field, type); + switch (type) { + case HAZZER: + printer->Print(" * @return Whether the $name$ field is set.\n", "name", + field->camelcase_name()); + break; + case GETTER: + printer->Print(" * @return The $name$.\n", "name", + field->camelcase_name()); + break; + case SETTER: + printer->Print(" * @param value The $name$ to set.\n", "name", + field->camelcase_name()); + break; + case CLEARER: + // Print nothing + break; + // Repeated + case LIST_COUNT: + printer->Print(" * @return The count of $name$.\n", "name", + field->camelcase_name()); + break; + case LIST_GETTER: + printer->Print(" * @return A list containing the $name$.\n", "name", + field->camelcase_name()); + break; + case LIST_INDEXED_GETTER: + printer->Print(" * @param index The index of the element to return.\n"); + printer->Print(" * @return The $name$ at the given index.\n", "name", + field->camelcase_name()); + break; + case LIST_INDEXED_SETTER: + printer->Print(" * @param index The index to set the value at.\n"); + printer->Print(" * @param value The $name$ to set.\n", "name", + field->camelcase_name()); + break; + case LIST_ADDER: + printer->Print(" * @param value The $name$ to add.\n", "name", + field->camelcase_name()); + break; + case LIST_MULTI_ADDER: + printer->Print(" * @param values The $name$ to add.\n", "name", + field->camelcase_name()); + break; + } + if (builder) { + printer->Print(" * @return This builder for chaining.\n"); + } + printer->Print(" */\n"); +} + +void WriteFieldEnumValueAccessorDocComment(io::Printer* printer, + const FieldDescriptor* field, + const FieldAccessorType type, + const bool builder) { + printer->Print("/**\n"); + WriteDocCommentBody(printer, field); + printer->Print(" * <code>$def$</code>\n", "def", + EscapeJavadoc(FirstLineOf(field->DebugString()))); + WriteDeprecatedJavadoc(printer, field, type); + switch (type) { + case HAZZER: + // Should never happen + break; + case GETTER: + printer->Print( + " * @return The enum numeric value on the wire for $name$.\n", "name", + field->camelcase_name()); + break; + case SETTER: + printer->Print( + " * @param value The enum numeric value on the wire for $name$ to " + "set.\n", + "name", field->camelcase_name()); + break; + case CLEARER: + // Print nothing + break; + // Repeated + case LIST_COUNT: + // Should never happen + break; + case LIST_GETTER: + printer->Print( + " * @return A list containing the enum numeric values on the wire " + "for $name$.\n", + "name", field->camelcase_name()); + break; + case LIST_INDEXED_GETTER: + printer->Print(" * @param index The index of the value to return.\n"); + printer->Print( + " * @return The enum numeric value on the wire of $name$ at the " + "given index.\n", + "name", field->camelcase_name()); + break; + case LIST_INDEXED_SETTER: + printer->Print(" * @param index The index to set the value at.\n"); + printer->Print( + " * @param value The enum numeric value on the wire for $name$ to " + "set.\n", + "name", field->camelcase_name()); + break; + case LIST_ADDER: + printer->Print( + " * @param value The enum numeric value on the wire for $name$ to " + "add.\n", + "name", field->camelcase_name()); + break; + case LIST_MULTI_ADDER: + printer->Print( + " * @param values The enum numeric values on the wire for $name$ to " + "add.\n", + "name", field->camelcase_name()); + break; + } + if (builder) { + printer->Print(" * @return This builder for chaining.\n"); + } + printer->Print(" */\n"); +} + +void WriteFieldStringBytesAccessorDocComment(io::Printer* printer, + const FieldDescriptor* field, + const FieldAccessorType type, + const bool builder) { + printer->Print("/**\n"); + WriteDocCommentBody(printer, field); + printer->Print(" * <code>$def$</code>\n", "def", + EscapeJavadoc(FirstLineOf(field->DebugString()))); + WriteDeprecatedJavadoc(printer, field, type); + switch (type) { + case HAZZER: + // Should never happen + break; + case GETTER: + printer->Print(" * @return The bytes for $name$.\n", "name", + field->camelcase_name()); + break; + case SETTER: + printer->Print(" * @param value The bytes for $name$ to set.\n", "name", + field->camelcase_name()); + break; + case CLEARER: + // Print nothing + break; + // Repeated + case LIST_COUNT: + // Should never happen + break; + case LIST_GETTER: + printer->Print(" * @return A list containing the bytes for $name$.\n", + "name", field->camelcase_name()); + break; + case LIST_INDEXED_GETTER: + printer->Print(" * @param index The index of the value to return.\n"); + printer->Print(" * @return The bytes of the $name$ at the given index.\n", + "name", field->camelcase_name()); + break; + case LIST_INDEXED_SETTER: + printer->Print(" * @param index The index to set the value at.\n"); + printer->Print(" * @param value The bytes of the $name$ to set.\n", + "name", field->camelcase_name()); + break; + case LIST_ADDER: + printer->Print(" * @param value The bytes of the $name$ to add.\n", + "name", field->camelcase_name()); + break; + case LIST_MULTI_ADDER: + printer->Print(" * @param values The bytes of the $name$ to add.\n", + "name", field->camelcase_name()); + break; + } + if (builder) { + printer->Print(" * @return This builder for chaining.\n"); + } + printer->Print(" */\n"); +} + +// Enum + +void WriteEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_) { + printer->Print("/**\n"); + WriteDocCommentBody(printer, enum_); + printer->Print( + " * Protobuf enum {@code $fullname$}\n" + " */\n", + "fullname", EscapeJavadoc(enum_->full_name())); +} + +void WriteEnumValueDocComment(io::Printer* printer, + const EnumValueDescriptor* value) { + printer->Print("/**\n"); + WriteDocCommentBody(printer, value); + printer->Print( + " * <code>$def$</code>\n" + " */\n", + "def", EscapeJavadoc(FirstLineOf(value->DebugString()))); +} + +void WriteServiceDocComment(io::Printer* printer, + const ServiceDescriptor* service) { + printer->Print("/**\n"); + WriteDocCommentBody(printer, service); + printer->Print( + " * Protobuf service {@code $fullname$}\n" + " */\n", + "fullname", EscapeJavadoc(service->full_name())); +} + +void WriteMethodDocComment(io::Printer* printer, + const MethodDescriptor* method) { + printer->Print("/**\n"); + WriteDocCommentBody(printer, method); + printer->Print( + " * <code>$def$</code>\n" + " */\n", + "def", EscapeJavadoc(FirstLineOf(method->DebugString()))); +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_doc_comment.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_doc_comment.h new file mode 100644 index 00000000..2706effb --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_doc_comment.h @@ -0,0 +1,101 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_DOC_COMMENT_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_DOC_COMMENT_H__ + +#include <descriptor.h> + +#include <port_def.inc> + +namespace google { +namespace protobuf { +namespace io { +class Printer; // printer.h +} +} // namespace protobuf +} // namespace google + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +enum FieldAccessorType { + HAZZER, + GETTER, + SETTER, + CLEARER, + // Repeated + LIST_COUNT, + LIST_GETTER, + LIST_INDEXED_GETTER, + LIST_INDEXED_SETTER, + LIST_ADDER, + LIST_MULTI_ADDER +}; + +void WriteMessageDocComment(io::Printer* printer, const Descriptor* message); +void WriteFieldDocComment(io::Printer* printer, const FieldDescriptor* field); +void WriteFieldAccessorDocComment(io::Printer* printer, + const FieldDescriptor* field, + const FieldAccessorType type, + const bool builder = false); +void WriteFieldEnumValueAccessorDocComment(io::Printer* printer, + const FieldDescriptor* field, + const FieldAccessorType type, + const bool builder = false); +void WriteFieldStringBytesAccessorDocComment(io::Printer* printer, + const FieldDescriptor* field, + const FieldAccessorType type, + const bool builder = false); +void WriteEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_); +void WriteEnumValueDocComment(io::Printer* printer, + const EnumValueDescriptor* value); +void WriteServiceDocComment(io::Printer* printer, + const ServiceDescriptor* service); +void WriteMethodDocComment(io::Printer* printer, + const MethodDescriptor* method); + +// Exposed for testing only. +PROTOC_EXPORT std::string EscapeJavadoc(const std::string& input); + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +#include <port_undef.inc> + +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_DOC_COMMENT_H__ diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_doc_comment_unittest.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_doc_comment_unittest.cc new file mode 100644 index 00000000..cbeadd0e --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_doc_comment_unittest.cc @@ -0,0 +1,67 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 <compiler/java/java_doc_comment.h> + +#include <gtest/gtest.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { +namespace { + +TEST(JavaDocCommentTest, Escaping) { + EXPECT_EQ("foo /* bar */ baz", EscapeJavadoc("foo /* bar */ baz")); + EXPECT_EQ("foo /*/ baz", EscapeJavadoc("foo /*/ baz")); + EXPECT_EQ("{@foo}", EscapeJavadoc("{@foo}")); + EXPECT_EQ("<i>&</i>", EscapeJavadoc("<i>&</i>")); + EXPECT_EQ("foo\u1234bar", EscapeJavadoc("foo\\u1234bar")); + EXPECT_EQ("@deprecated", EscapeJavadoc("@deprecated")); +} + +// TODO(kenton): It's hard to write a robust test of the doc comments -- we +// can only really compare the output against a golden value, which is a +// fairly tedious and fragile testing strategy. If we want to go that route, +// it probably makes sense to bite the bullet and write a test that compares +// the whole generated output for unittest.proto against a golden value, with +// a very simple script that can be run to regenerate it with the latest code. +// This would mean that updates to the golden file would have to be included +// in any change to the code generator, which would actually be fairly useful +// as it allows the reviewer to see clearly how the generated code is +// changing. + +} // namespace +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum.cc new file mode 100644 index 00000000..f3eb4bc2 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum.cc @@ -0,0 +1,391 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <map> +#include <string> + +#include <compiler/java/java_context.h> +#include <compiler/java/java_doc_comment.h> +#include <compiler/java/java_enum.h> +#include <compiler/java/java_helpers.h> +#include <compiler/java/java_name_resolver.h> +#include <descriptor.pb.h> +#include <io/printer.h> +#include <stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor, + bool immutable_api, Context* context) + : descriptor_(descriptor), + immutable_api_(immutable_api), + context_(context), + name_resolver_(context->GetNameResolver()) { + for (int i = 0; i < descriptor_->value_count(); i++) { + const EnumValueDescriptor* value = descriptor_->value(i); + const EnumValueDescriptor* canonical_value = + descriptor_->FindValueByNumber(value->number()); + + if (value == canonical_value) { + canonical_values_.push_back(value); + } else { + Alias alias; + alias.value = value; + alias.canonical_value = canonical_value; + aliases_.push_back(alias); + } + } +} + +EnumGenerator::~EnumGenerator() {} + +void EnumGenerator::Generate(io::Printer* printer) { + WriteEnumDocComment(printer, descriptor_); + MaybePrintGeneratedAnnotation(context_, printer, descriptor_, immutable_api_); + printer->Print( + "$deprecation$public enum $classname$\n" + " implements com.google.protobuf.ProtocolMessageEnum {\n", + "classname", descriptor_->name(), "deprecation", + descriptor_->options().deprecated() ? "@java.lang.Deprecated " : ""); + printer->Annotate("classname", descriptor_); + printer->Indent(); + + bool ordinal_is_index = true; + std::string index_text = "ordinal()"; + for (int i = 0; i < canonical_values_.size(); i++) { + if (canonical_values_[i]->index() != i) { + ordinal_is_index = false; + index_text = "index"; + break; + } + } + + for (int i = 0; i < canonical_values_.size(); i++) { + std::map<std::string, std::string> vars; + vars["name"] = canonical_values_[i]->name(); + vars["index"] = StrCat(canonical_values_[i]->index()); + vars["number"] = StrCat(canonical_values_[i]->number()); + WriteEnumValueDocComment(printer, canonical_values_[i]); + if (canonical_values_[i]->options().deprecated()) { + printer->Print("@java.lang.Deprecated\n"); + } + if (ordinal_is_index) { + printer->Print(vars, "$name$($number$),\n"); + } else { + printer->Print(vars, "$name$($index$, $number$),\n"); + } + printer->Annotate("name", canonical_values_[i]); + } + + if (SupportUnknownEnumValue(descriptor_->file())) { + if (ordinal_is_index) { + printer->Print("${$UNRECOGNIZED$}$(-1),\n", "{", "", "}", ""); + } else { + printer->Print("${$UNRECOGNIZED$}$(-1, -1),\n", "{", "", "}", ""); + } + printer->Annotate("{", "}", descriptor_); + } + + printer->Print( + ";\n" + "\n"); + + // ----------------------------------------------------------------- + + for (int i = 0; i < aliases_.size(); i++) { + std::map<std::string, std::string> vars; + vars["classname"] = descriptor_->name(); + vars["name"] = aliases_[i].value->name(); + vars["canonical_name"] = aliases_[i].canonical_value->name(); + WriteEnumValueDocComment(printer, aliases_[i].value); + printer->Print( + vars, "public static final $classname$ $name$ = $canonical_name$;\n"); + printer->Annotate("name", aliases_[i].value); + } + + for (int i = 0; i < descriptor_->value_count(); i++) { + std::map<std::string, std::string> vars; + vars["name"] = descriptor_->value(i)->name(); + vars["number"] = StrCat(descriptor_->value(i)->number()); + vars["{"] = ""; + vars["}"] = ""; + vars["deprecation"] = descriptor_->value(i)->options().deprecated() + ? "@java.lang.Deprecated " + : ""; + WriteEnumValueDocComment(printer, descriptor_->value(i)); + printer->Print(vars, + "$deprecation$public static final int ${$$name$_VALUE$}$ = " + "$number$;\n"); + printer->Annotate("{", "}", descriptor_->value(i)); + } + printer->Print("\n"); + + // ----------------------------------------------------------------- + + printer->Print( + "\n" + "public final int getNumber() {\n"); + if (SupportUnknownEnumValue(descriptor_->file())) { + if (ordinal_is_index) { + printer->Print( + " if (this == UNRECOGNIZED) {\n" + " throw new java.lang.IllegalArgumentException(\n" + " \"Can't get the number of an unknown enum value.\");\n" + " }\n"); + } else { + printer->Print( + " if (index == -1) {\n" + " throw new java.lang.IllegalArgumentException(\n" + " \"Can't get the number of an unknown enum value.\");\n" + " }\n"); + } + } + printer->Print( + " return value;\n" + "}\n" + "\n" + "/**\n" + " * @param value The numeric wire value of the corresponding enum " + "entry.\n" + " * @return The enum associated with the given numeric wire value.\n" + " * @deprecated Use {@link #forNumber(int)} instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "public static $classname$ valueOf(int value) {\n" + " return forNumber(value);\n" + "}\n" + "\n" + "/**\n" + " * @param value The numeric wire value of the corresponding enum " + "entry.\n" + " * @return The enum associated with the given numeric wire value.\n" + " */\n" + "public static $classname$ forNumber(int value) {\n" + " switch (value) {\n", + "classname", descriptor_->name()); + printer->Indent(); + printer->Indent(); + + for (int i = 0; i < canonical_values_.size(); i++) { + printer->Print("case $number$: return $name$;\n", "name", + canonical_values_[i]->name(), "number", + StrCat(canonical_values_[i]->number())); + } + + printer->Outdent(); + printer->Outdent(); + printer->Print( + " default: return null;\n" + " }\n" + "}\n" + "\n" + "public static com.google.protobuf.Internal.EnumLiteMap<$classname$>\n" + " internalGetValueMap() {\n" + " return internalValueMap;\n" + "}\n" + "private static final com.google.protobuf.Internal.EnumLiteMap<\n" + " $classname$> internalValueMap =\n" + " new com.google.protobuf.Internal.EnumLiteMap<$classname$>() {\n" + " public $classname$ findValueByNumber(int number) {\n" + " return $classname$.forNumber(number);\n" + " }\n" + " };\n" + "\n", + "classname", descriptor_->name()); + + // ----------------------------------------------------------------- + // Reflection + + if (HasDescriptorMethods(descriptor_, context_->EnforceLite())) { + printer->Print( + "public final com.google.protobuf.Descriptors.EnumValueDescriptor\n" + " getValueDescriptor() {\n"); + if (SupportUnknownEnumValue(descriptor_->file())) { + if (ordinal_is_index) { + printer->Print( + " if (this == UNRECOGNIZED) {\n" + " throw new java.lang.IllegalStateException(\n" + " \"Can't get the descriptor of an unrecognized enum " + "value.\");\n" + " }\n"); + } else { + printer->Print( + " if (index == -1) {\n" + " throw new java.lang.IllegalStateException(\n" + " \"Can't get the descriptor of an unrecognized enum " + "value.\");\n" + " }\n"); + } + } + printer->Print( + " return getDescriptor().getValues().get($index_text$);\n" + "}\n" + "public final com.google.protobuf.Descriptors.EnumDescriptor\n" + " getDescriptorForType() {\n" + " return getDescriptor();\n" + "}\n" + "public static final com.google.protobuf.Descriptors.EnumDescriptor\n" + " getDescriptor() {\n", + "index_text", index_text); + + // TODO(kenton): Cache statically? Note that we can't access descriptors + // at module init time because it wouldn't work with descriptor.proto, but + // we can cache the value the first time getDescriptor() is called. + if (descriptor_->containing_type() == NULL) { + // The class generated for the File fully populates the descriptor with + // extensions in both the mutable and immutable cases. (In the mutable api + // this is accomplished by attempting to load the immutable outer class). + printer->Print( + " return $file$.getDescriptor().getEnumTypes().get($index$);\n", + "file", + name_resolver_->GetClassName(descriptor_->file(), immutable_api_), + "index", StrCat(descriptor_->index())); + } else { + printer->Print( + " return $parent$.$descriptor$.getEnumTypes().get($index$);\n", + "parent", + name_resolver_->GetClassName(descriptor_->containing_type(), + immutable_api_), + "descriptor", + descriptor_->containing_type() + ->options() + .no_standard_descriptor_accessor() + ? "getDefaultInstance().getDescriptorForType()" + : "getDescriptor()", + "index", StrCat(descriptor_->index())); + } + + printer->Print( + "}\n" + "\n" + "private static final $classname$[] VALUES = ", + "classname", descriptor_->name()); + + if (CanUseEnumValues()) { + // If the constants we are going to output are exactly the ones we + // have declared in the Java enum in the same order, then we can use + // the values() method that the Java compiler automatically generates + // for every enum. + printer->Print("values();\n"); + } else { + printer->Print("getStaticValuesArray();\n"); + printer->Print("private static $classname$[] getStaticValuesArray() {\n", + "classname", descriptor_->name()); + printer->Indent(); + printer->Print( + "return new $classname$[] {\n" + " ", + "classname", descriptor_->name()); + for (int i = 0; i < descriptor_->value_count(); i++) { + printer->Print("$name$, ", "name", descriptor_->value(i)->name()); + } + printer->Print( + "\n" + "};\n"); + printer->Outdent(); + printer->Print("}"); + } + + printer->Print( + "\n" + "public static $classname$ valueOf(\n" + " com.google.protobuf.Descriptors.EnumValueDescriptor desc) {\n" + " if (desc.getType() != getDescriptor()) {\n" + " throw new java.lang.IllegalArgumentException(\n" + " \"EnumValueDescriptor is not for this type.\");\n" + " }\n", + "classname", descriptor_->name()); + if (SupportUnknownEnumValue(descriptor_->file())) { + printer->Print( + " if (desc.getIndex() == -1) {\n" + " return UNRECOGNIZED;\n" + " }\n"); + } + printer->Print( + " return VALUES[desc.getIndex()];\n" + "}\n" + "\n"); + + if (!ordinal_is_index) { + printer->Print("private final int index;\n"); + } + } + + // ----------------------------------------------------------------- + + printer->Print("private final int value;\n\n"); + + if (ordinal_is_index) { + printer->Print("private $classname$(int value) {\n", "classname", + descriptor_->name()); + } else { + printer->Print("private $classname$(int index, int value) {\n", "classname", + descriptor_->name()); + } + if (HasDescriptorMethods(descriptor_, context_->EnforceLite()) && + !ordinal_is_index) { + printer->Print(" this.index = index;\n"); + } + printer->Print( + " this.value = value;\n" + "}\n"); + + printer->Print( + "\n" + "// @@protoc_insertion_point(enum_scope:$full_name$)\n", + "full_name", descriptor_->full_name()); + + printer->Outdent(); + printer->Print("}\n\n"); +} + +bool EnumGenerator::CanUseEnumValues() { + if (canonical_values_.size() != descriptor_->value_count()) { + return false; + } + for (int i = 0; i < descriptor_->value_count(); i++) { + if (descriptor_->value(i)->name() != canonical_values_[i]->name()) { + return false; + } + } + return true; +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum.h new file mode 100644 index 00000000..cae2ffea --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum.h @@ -0,0 +1,100 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_H__ + +#include <string> +#include <vector> +#include <descriptor.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { +class Context; // context.h +class ClassNameResolver; // name_resolver.h +} // namespace java +} // namespace compiler +namespace io { +class Printer; // printer.h +} +} // namespace protobuf +} // namespace google + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +class EnumGenerator { + public: + EnumGenerator(const EnumDescriptor* descriptor, bool immutable_api, + Context* context); + ~EnumGenerator(); + + void Generate(io::Printer* printer); + + private: + const EnumDescriptor* descriptor_; + + // The proto language allows multiple enum constants to have the same + // numeric value. Java, however, does not allow multiple enum constants to + // be considered equivalent. We treat the first defined constant for any + // given numeric value as "canonical" and the rest as aliases of that + // canonical value. + std::vector<const EnumValueDescriptor*> canonical_values_; + + struct Alias { + const EnumValueDescriptor* value; + const EnumValueDescriptor* canonical_value; + }; + std::vector<Alias> aliases_; + + bool immutable_api_; + + Context* context_; + ClassNameResolver* name_resolver_; + + bool CanUseEnumValues(); + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_H__ diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_field.cc new file mode 100644 index 00000000..51e944df --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_field.cc @@ -0,0 +1,1176 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <compiler/java/java_enum_field.h> + +#include <cstdint> +#include <map> +#include <string> + +#include <stubs/logging.h> +#include <stubs/common.h> +#include <compiler/java/java_context.h> +#include <compiler/java/java_doc_comment.h> +#include <compiler/java/java_helpers.h> +#include <compiler/java/java_name_resolver.h> +#include <io/printer.h> +#include <wire_format.h> +#include <stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +namespace { + +void SetEnumVariables(const FieldDescriptor* descriptor, int messageBitIndex, + int builderBitIndex, const FieldGeneratorInfo* info, + ClassNameResolver* name_resolver, + std::map<std::string, std::string>* variables) { + SetCommonFieldVariables(descriptor, info, variables); + + (*variables)["type"] = + name_resolver->GetImmutableClassName(descriptor->enum_type()); + (*variables)["kt_type"] = (*variables)["type"]; + (*variables)["mutable_type"] = + name_resolver->GetMutableClassName(descriptor->enum_type()); + (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver); + (*variables)["default_number"] = + StrCat(descriptor->default_value_enum()->number()); + (*variables)["tag"] = StrCat( + static_cast<int32_t>(internal::WireFormat::MakeTag(descriptor))); + (*variables)["tag_size"] = StrCat( + internal::WireFormat::TagSize(descriptor->number(), GetType(descriptor))); + // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported + // by the proto compiler + (*variables)["deprecation"] = + descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; + (*variables)["kt_deprecation"] = + descriptor->options().deprecated() + ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] + + " is deprecated\") " + : ""; + (*variables)["on_changed"] = "onChanged();"; + // Use deprecated valueOf() method to be compatible with old generated code + // for v2.5.0/v2.6.1. + // TODO(xiaofeng): Use "forNumber" when we no longer support compatibility + // with v2.5.0/v2.6.1, and remove the @SuppressWarnings annotations. + (*variables)["for_number"] = "valueOf"; + + if (HasHasbit(descriptor)) { + // For singular messages and builders, one bit is used for the hasField bit. + (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); + (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex); + + // Note that these have a trailing ";". + (*variables)["set_has_field_bit_message"] = + GenerateSetBit(messageBitIndex) + ";"; + (*variables)["set_has_field_bit_builder"] = + GenerateSetBit(builderBitIndex) + ";"; + (*variables)["clear_has_field_bit_builder"] = + GenerateClearBit(builderBitIndex) + ";"; + + (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex); + } else { + (*variables)["set_has_field_bit_message"] = ""; + (*variables)["set_has_field_bit_builder"] = ""; + (*variables)["clear_has_field_bit_builder"] = ""; + + (*variables)["is_field_present_message"] = + (*variables)["name"] + "_ != " + (*variables)["default"] + + ".getNumber()"; + } + + // For repeated builders, one bit is used for whether the array is immutable. + (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex); + (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex); + (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex); + + // For repeated fields, one bit is used for whether the array is immutable + // in the parsing constructor. + (*variables)["get_mutable_bit_parser"] = + GenerateGetBitMutableLocal(builderBitIndex); + (*variables)["set_mutable_bit_parser"] = + GenerateSetBitMutableLocal(builderBitIndex); + + (*variables)["get_has_field_bit_from_local"] = + GenerateGetBitFromLocal(builderBitIndex); + (*variables)["set_has_field_bit_to_local"] = + GenerateSetBitToLocal(messageBitIndex); + + if (SupportUnknownEnumValue(descriptor->file())) { + (*variables)["unknown"] = (*variables)["type"] + ".UNRECOGNIZED"; + } else { + (*variables)["unknown"] = (*variables)["default"]; + } +} + +} // namespace + +// =================================================================== + +ImmutableEnumFieldGenerator::ImmutableEnumFieldGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, + Context* context) + : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) { + SetEnumVariables(descriptor, messageBitIndex, builderBitIndex, + context->GetFieldGeneratorInfo(descriptor), name_resolver_, + &variables_); +} + +ImmutableEnumFieldGenerator::~ImmutableEnumFieldGenerator() {} + +int ImmutableEnumFieldGenerator::GetNumBitsForMessage() const { + return HasHasbit(descriptor_) ? 1 : 0; +} + +int ImmutableEnumFieldGenerator::GetNumBitsForBuilder() const { + return GetNumBitsForMessage(); +} + +void ImmutableEnumFieldGenerator::GenerateInterfaceMembers( + io::Printer* printer) const { + if (HasHazzer(descriptor_)) { + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print(variables_, + "$deprecation$boolean has$capitalized_name$();\n"); + } + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, + "$deprecation$int get$capitalized_name$Value();\n"); + } + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n"); +} + +void ImmutableEnumFieldGenerator::GenerateMembers(io::Printer* printer) const { + printer->Print(variables_, "private int $name$_;\n"); + PrintExtraFieldInfo(variables_, printer); + if (HasHazzer(descriptor_)) { + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print(variables_, + "@java.lang.Override $deprecation$public boolean " + "${$has$capitalized_name$$}$() {\n" + " return $get_has_field_bit_message$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, + "@java.lang.Override $deprecation$public int " + "${$get$capitalized_name$Value$}$() {\n" + " return $name$_;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, + "@java.lang.Override $deprecation$public $type$ " + "${$get$capitalized_name$$}$() {\n" + " @SuppressWarnings(\"deprecation\")\n" + " $type$ result = $type$.$for_number$($name$_);\n" + " return result == null ? $unknown$ : result;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +void ImmutableEnumFieldGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + printer->Print(variables_, "private int $name$_ = $default_number$;\n"); + if (HasHazzer(descriptor_)) { + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print(variables_, + "@java.lang.Override $deprecation$public boolean " + "${$has$capitalized_name$$}$() {\n" + " return $get_has_field_bit_builder$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, + "@java.lang.Override $deprecation$public int " + "${$get$capitalized_name$Value$}$() {\n" + " return $name$_;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder " + "${$set$capitalized_name$Value$}$(int value) {\n" + " $set_has_field_bit_builder$\n" + " $name$_ = value;\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" + " @SuppressWarnings(\"deprecation\")\n" + " $type$ result = $type$.$for_number$($name$_);\n" + " return result == null ? $unknown$ : result;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, SETTER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder " + "${$set$capitalized_name$$}$($type$ value) {\n" + " if (value == null) {\n" + " throw new NullPointerException();\n" + " }\n" + " $set_has_field_bit_builder$\n" + " $name$_ = value.getNumber();\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ true); + printer->Print( + variables_, + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" + " $clear_has_field_bit_builder$\n" + " $name$_ = $default_number$;\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +void ImmutableEnumFieldGenerator::GenerateKotlinDslMembers( + io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$kt_deprecation$public var $kt_name$: $kt_type$\n" + " @JvmName(\"${$get$kt_capitalized_name$$}$\")\n" + " get() = $kt_dsl_builder$.${$get$capitalized_name$$}$()\n" + " @JvmName(\"${$set$kt_capitalized_name$$}$\")\n" + " set(value) {\n" + " $kt_dsl_builder$.${$set$capitalized_name$$}$(value)\n" + " }\n"); + + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ false); + printer->Print(variables_, + "public fun ${$clear$kt_capitalized_name$$}$() {\n" + " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n" + "}\n"); + + if (HasHazzer(descriptor_)) { + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print( + variables_, + "public fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n" + " return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n" + "}\n"); + } +} + +void ImmutableEnumFieldGenerator::GenerateFieldBuilderInitializationCode( + io::Printer* printer) const { + // noop for enums +} + +void ImmutableEnumFieldGenerator::GenerateInitializationCode( + io::Printer* printer) const { + printer->Print(variables_, "$name$_ = $default_number$;\n"); +} + +void ImmutableEnumFieldGenerator::GenerateBuilderClearCode( + io::Printer* printer) const { + printer->Print(variables_, + "$name$_ = $default_number$;\n" + "$clear_has_field_bit_builder$\n"); +} + +void ImmutableEnumFieldGenerator::GenerateMergingCode( + io::Printer* printer) const { + if (HasHazzer(descriptor_)) { + printer->Print(variables_, + "if (other.has$capitalized_name$()) {\n" + " set$capitalized_name$(other.get$capitalized_name$());\n" + "}\n"); + } else if (SupportUnknownEnumValue(descriptor_->file())) { + printer->Print( + variables_, + "if (other.$name$_ != $default_number$) {\n" + " set$capitalized_name$Value(other.get$capitalized_name$Value());\n" + "}\n"); + } else { + GOOGLE_LOG(FATAL) << "Can't reach here."; + } +} + +void ImmutableEnumFieldGenerator::GenerateBuildingCode( + io::Printer* printer) const { + if (HasHazzer(descriptor_)) { + printer->Print(variables_, + "if ($get_has_field_bit_from_local$) {\n" + " $set_has_field_bit_to_local$;\n" + "}\n"); + } + printer->Print(variables_, "result.$name$_ = $name$_;\n"); +} + +void ImmutableEnumFieldGenerator::GenerateParsingCode( + io::Printer* printer) const { + if (SupportUnknownEnumValue(descriptor_->file())) { + printer->Print(variables_, + "int rawValue = input.readEnum();\n" + "$set_has_field_bit_message$\n" + "$name$_ = rawValue;\n"); + } else { + printer->Print(variables_, + "int rawValue = input.readEnum();\n" + " @SuppressWarnings(\"deprecation\")\n" + "$type$ value = $type$.$for_number$(rawValue);\n" + "if (value == null) {\n" + " unknownFields.mergeVarintField($number$, rawValue);\n" + "} else {\n" + " $set_has_field_bit_message$\n" + " $name$_ = rawValue;\n" + "}\n"); + } +} + +void ImmutableEnumFieldGenerator::GenerateParsingDoneCode( + io::Printer* printer) const { + // noop for enums +} + +void ImmutableEnumFieldGenerator::GenerateSerializationCode( + io::Printer* printer) const { + printer->Print(variables_, + "if ($is_field_present_message$) {\n" + " output.writeEnum($number$, $name$_);\n" + "}\n"); +} + +void ImmutableEnumFieldGenerator::GenerateSerializedSizeCode( + io::Printer* printer) const { + printer->Print(variables_, + "if ($is_field_present_message$) {\n" + " size += com.google.protobuf.CodedOutputStream\n" + " .computeEnumSize($number$, $name$_);\n" + "}\n"); +} + +void ImmutableEnumFieldGenerator::GenerateEqualsCode( + io::Printer* printer) const { + printer->Print(variables_, "if ($name$_ != other.$name$_) return false;\n"); +} + +void ImmutableEnumFieldGenerator::GenerateHashCode(io::Printer* printer) const { + printer->Print(variables_, + "hash = (37 * hash) + $constant_name$;\n" + "hash = (53 * hash) + $name$_;\n"); +} + +std::string ImmutableEnumFieldGenerator::GetBoxedType() const { + return name_resolver_->GetImmutableClassName(descriptor_->enum_type()); +} + +// =================================================================== + +ImmutableEnumOneofFieldGenerator::ImmutableEnumOneofFieldGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, + Context* context) + : ImmutableEnumFieldGenerator(descriptor, messageBitIndex, builderBitIndex, + context) { + const OneofGeneratorInfo* info = + context->GetOneofGeneratorInfo(descriptor->containing_oneof()); + SetCommonOneofVariables(descriptor, info, &variables_); +} + +ImmutableEnumOneofFieldGenerator::~ImmutableEnumOneofFieldGenerator() {} + +void ImmutableEnumOneofFieldGenerator::GenerateMembers( + io::Printer* printer) const { + PrintExtraFieldInfo(variables_, printer); + GOOGLE_DCHECK(HasHazzer(descriptor_)); + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print(variables_, + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return $has_oneof_case_message$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER); + printer->Print( + variables_, + "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n" + " if ($has_oneof_case_message$) {\n" + " return (java.lang.Integer) $oneof_name$_;\n" + " }\n" + " return $default_number$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" + " if ($has_oneof_case_message$) {\n" + " @SuppressWarnings(\"deprecation\")\n" + " $type$ result = $type$.$for_number$(\n" + " (java.lang.Integer) $oneof_name$_);\n" + " return result == null ? $unknown$ : result;\n" + " }\n" + " return $default$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +void ImmutableEnumOneofFieldGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + GOOGLE_DCHECK(HasHazzer(descriptor_)); + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return $has_oneof_case_message$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n" + " if ($has_oneof_case_message$) {\n" + " return ((java.lang.Integer) $oneof_name$_).intValue();\n" + " }\n" + " return $default_number$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder " + "${$set$capitalized_name$Value$}$(int value) {\n" + " $set_oneof_case_message$;\n" + " $oneof_name$_ = value;\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" + " if ($has_oneof_case_message$) {\n" + " @SuppressWarnings(\"deprecation\")\n" + " $type$ result = $type$.$for_number$(\n" + " (java.lang.Integer) $oneof_name$_);\n" + " return result == null ? $unknown$ : result;\n" + " }\n" + " return $default$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, SETTER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder " + "${$set$capitalized_name$$}$($type$ value) {\n" + " if (value == null) {\n" + " throw new NullPointerException();\n" + " }\n" + " $set_oneof_case_message$;\n" + " $oneof_name$_ = value.getNumber();\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ true); + printer->Print( + variables_, + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" + " if ($has_oneof_case_message$) {\n" + " $clear_oneof_case_message$;\n" + " $oneof_name$_ = null;\n" + " $on_changed$\n" + " }\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +void ImmutableEnumOneofFieldGenerator::GenerateBuildingCode( + io::Printer* printer) const { + printer->Print(variables_, + "if ($has_oneof_case_message$) {\n" + " result.$oneof_name$_ = $oneof_name$_;\n" + "}\n"); +} + +void ImmutableEnumOneofFieldGenerator::GenerateMergingCode( + io::Printer* printer) const { + if (SupportUnknownEnumValue(descriptor_->file())) { + printer->Print( + variables_, + "set$capitalized_name$Value(other.get$capitalized_name$Value());\n"); + } else { + printer->Print(variables_, + "set$capitalized_name$(other.get$capitalized_name$());\n"); + } +} + +void ImmutableEnumOneofFieldGenerator::GenerateParsingCode( + io::Printer* printer) const { + if (SupportUnknownEnumValue(descriptor_->file())) { + printer->Print(variables_, + "int rawValue = input.readEnum();\n" + "$set_oneof_case_message$;\n" + "$oneof_name$_ = rawValue;\n"); + } else { + printer->Print(variables_, + "int rawValue = input.readEnum();\n" + "@SuppressWarnings(\"deprecation\")\n" + "$type$ value = $type$.$for_number$(rawValue);\n" + "if (value == null) {\n" + " unknownFields.mergeVarintField($number$, rawValue);\n" + "} else {\n" + " $set_oneof_case_message$;\n" + " $oneof_name$_ = rawValue;\n" + "}\n"); + } +} + +void ImmutableEnumOneofFieldGenerator::GenerateSerializationCode( + io::Printer* printer) const { + printer->Print( + variables_, + "if ($has_oneof_case_message$) {\n" + " output.writeEnum($number$, ((java.lang.Integer) $oneof_name$_));\n" + "}\n"); +} + +void ImmutableEnumOneofFieldGenerator::GenerateSerializedSizeCode( + io::Printer* printer) const { + printer->Print( + variables_, + "if ($has_oneof_case_message$) {\n" + " size += com.google.protobuf.CodedOutputStream\n" + " .computeEnumSize($number$, ((java.lang.Integer) $oneof_name$_));\n" + "}\n"); +} + +void ImmutableEnumOneofFieldGenerator::GenerateEqualsCode( + io::Printer* printer) const { + if (SupportUnknownEnumValue(descriptor_->file())) { + printer->Print( + variables_, + "if (get$capitalized_name$Value()\n" + " != other.get$capitalized_name$Value()) return false;\n"); + } else { + printer->Print( + variables_, + "if (!get$capitalized_name$()\n" + " .equals(other.get$capitalized_name$())) return false;\n"); + } +} + +void ImmutableEnumOneofFieldGenerator::GenerateHashCode( + io::Printer* printer) const { + if (SupportUnknownEnumValue(descriptor_->file())) { + printer->Print(variables_, + "hash = (37 * hash) + $constant_name$;\n" + "hash = (53 * hash) + get$capitalized_name$Value();\n"); + } else { + printer->Print( + variables_, + "hash = (37 * hash) + $constant_name$;\n" + "hash = (53 * hash) + get$capitalized_name$().getNumber();\n"); + } +} + +// =================================================================== + +RepeatedImmutableEnumFieldGenerator::RepeatedImmutableEnumFieldGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, + Context* context) + : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) { + SetEnumVariables(descriptor, messageBitIndex, builderBitIndex, + context->GetFieldGeneratorInfo(descriptor), name_resolver_, + &variables_); +} + +RepeatedImmutableEnumFieldGenerator::~RepeatedImmutableEnumFieldGenerator() {} + +int RepeatedImmutableEnumFieldGenerator::GetNumBitsForMessage() const { + return 0; +} + +int RepeatedImmutableEnumFieldGenerator::GetNumBitsForBuilder() const { + return 1; +} + +void RepeatedImmutableEnumFieldGenerator::GenerateInterfaceMembers( + io::Printer* printer) const { + WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER); + printer->Print( + variables_, + "$deprecation$java.util.List<$type$> get$capitalized_name$List();\n"); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT); + printer->Print(variables_, + "$deprecation$int get$capitalized_name$Count();\n"); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER); + printer->Print(variables_, + "$deprecation$$type$ get$capitalized_name$(int index);\n"); + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_GETTER); + printer->Print(variables_, + "$deprecation$java.util.List<java.lang.Integer>\n" + "get$capitalized_name$ValueList();\n"); + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, + LIST_INDEXED_GETTER); + printer->Print(variables_, + "$deprecation$int get$capitalized_name$Value(int index);\n"); + } +} + +void RepeatedImmutableEnumFieldGenerator::GenerateMembers( + io::Printer* printer) const { + printer->Print( + variables_, + "private java.util.List<java.lang.Integer> $name$_;\n" + "private static final " + "com.google.protobuf.Internal.ListAdapter.Converter<\n" + " java.lang.Integer, $type$> $name$_converter_ =\n" + " new com.google.protobuf.Internal.ListAdapter.Converter<\n" + " java.lang.Integer, $type$>() {\n" + " public $type$ convert(java.lang.Integer from) {\n" + " @SuppressWarnings(\"deprecation\")\n" + " $type$ result = $type$.$for_number$(from);\n" + " return result == null ? $unknown$ : result;\n" + " }\n" + " };\n"); + PrintExtraFieldInfo(variables_, printer); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public java.util.List<$type$> " + "${$get$capitalized_name$List$}$() {\n" + " return new com.google.protobuf.Internal.ListAdapter<\n" + " java.lang.Integer, $type$>($name$_, $name$_converter_);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" + " return $name$_.size();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" + " return $name$_converter_.convert($name$_.get(index));\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public java.util.List<java.lang.Integer>\n" + "${$get$capitalized_name$ValueList$}$() {\n" + " return $name$_;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, + LIST_INDEXED_GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public int " + "${$get$capitalized_name$Value$}$(int index) {\n" + " return $name$_.get(index);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } + + if (descriptor_->is_packed()) { + printer->Print(variables_, "private int $name$MemoizedSerializedSize;\n"); + } +} + +void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + printer->Print( + variables_, + // One field is the list and the other field keeps track of whether the + // list is immutable. If it's immutable, the invariant is that it must + // either an instance of Collections.emptyList() or it's an ArrayList + // wrapped in a Collections.unmodifiableList() wrapper and nobody else has + // a reference to the underlying ArrayList. This invariant allows us to + // share instances of lists between protocol buffers avoiding expensive + // memory allocations. Note, immutable is a strong guarantee here -- not + // just that the list cannot be modified via the reference but that the + // list can never be modified. + "private java.util.List<java.lang.Integer> $name$_ =\n" + " java.util.Collections.emptyList();\n" + + "private void ensure$capitalized_name$IsMutable() {\n" + " if (!$get_mutable_bit_builder$) {\n" + " $name$_ = new java.util.ArrayList<java.lang.Integer>($name$_);\n" + " $set_mutable_bit_builder$;\n" + " }\n" + "}\n"); + + WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER); + printer->Print( + variables_, + // Note: We return an unmodifiable list because otherwise the caller + // could hold on to the returned list and modify it after the message + // has been built, thus mutating the message which is supposed to be + // immutable. + "$deprecation$public java.util.List<$type$> " + "${$get$capitalized_name$List$}$() {\n" + " return new com.google.protobuf.Internal.ListAdapter<\n" + " java.lang.Integer, $type$>($name$_, $name$_converter_);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT); + printer->Print( + variables_, + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" + " return $name$_.size();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER); + printer->Print( + variables_, + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" + " return $name$_converter_.convert($name$_.get(index));\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" + " int index, $type$ value) {\n" + " if (value == null) {\n" + " throw new NullPointerException();\n" + " }\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.set(index, value.getNumber());\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder " + "${$add$capitalized_name$$}$($type$ value) {\n" + " if (value == null) {\n" + " throw new NullPointerException();\n" + " }\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.add(value.getNumber());\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n" + " java.lang.Iterable<? extends $type$> values) {\n" + " ensure$capitalized_name$IsMutable();\n" + " for ($type$ value : values) {\n" + " $name$_.add(value.getNumber());\n" + " }\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ true); + printer->Print( + variables_, + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" + " $name$_ = java.util.Collections.emptyList();\n" + " $clear_mutable_bit_builder$;\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_GETTER); + printer->Print(variables_, + "$deprecation$public java.util.List<java.lang.Integer>\n" + "${$get$capitalized_name$ValueList$}$() {\n" + " return java.util.Collections.unmodifiableList($name$_);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, + LIST_INDEXED_GETTER); + printer->Print(variables_, + "$deprecation$public int " + "${$get$capitalized_name$Value$}$(int index) {\n" + " return $name$_.get(index);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, + LIST_INDEXED_GETTER, + /* builder */ true); + printer->Print( + variables_, + "$deprecation$public Builder ${$set$capitalized_name$Value$}$(\n" + " int index, int value) {\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.set(index, value);\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_ADDER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder " + "${$add$capitalized_name$Value$}$(int value) {\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.add(value);\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, + LIST_MULTI_ADDER, /* builder */ true); + printer->Print( + variables_, + "$deprecation$public Builder ${$addAll$capitalized_name$Value$}$(\n" + " java.lang.Iterable<java.lang.Integer> values) {\n" + " ensure$capitalized_name$IsMutable();\n" + " for (int value : values) {\n" + " $name$_.add(value);\n" + " }\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } +} + +void RepeatedImmutableEnumFieldGenerator:: + GenerateFieldBuilderInitializationCode(io::Printer* printer) const { + // noop for enums +} + +void RepeatedImmutableEnumFieldGenerator::GenerateInitializationCode( + io::Printer* printer) const { + printer->Print(variables_, "$name$_ = java.util.Collections.emptyList();\n"); +} + +void RepeatedImmutableEnumFieldGenerator::GenerateBuilderClearCode( + io::Printer* printer) const { + printer->Print(variables_, + "$name$_ = java.util.Collections.emptyList();\n" + "$clear_mutable_bit_builder$;\n"); +} + +void RepeatedImmutableEnumFieldGenerator::GenerateMergingCode( + io::Printer* printer) const { + // The code below does two optimizations: + // 1. If the other list is empty, there's nothing to do. This ensures we + // don't allocate a new array if we already have an immutable one. + // 2. If the other list is non-empty and our current list is empty, we can + // reuse the other list which is guaranteed to be immutable. + printer->Print(variables_, + "if (!other.$name$_.isEmpty()) {\n" + " if ($name$_.isEmpty()) {\n" + " $name$_ = other.$name$_;\n" + " $clear_mutable_bit_builder$;\n" + " } else {\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.addAll(other.$name$_);\n" + " }\n" + " $on_changed$\n" + "}\n"); +} + +void RepeatedImmutableEnumFieldGenerator::GenerateBuildingCode( + io::Printer* printer) const { + // The code below ensures that the result has an immutable list. If our + // list is immutable, we can just reuse it. If not, we make it immutable. + printer->Print( + variables_, + "if ($get_mutable_bit_builder$) {\n" + " $name$_ = java.util.Collections.unmodifiableList($name$_);\n" + " $clear_mutable_bit_builder$;\n" + "}\n" + "result.$name$_ = $name$_;\n"); +} + +void RepeatedImmutableEnumFieldGenerator::GenerateParsingCode( + io::Printer* printer) const { + // Read and store the enum + if (SupportUnknownEnumValue(descriptor_->file())) { + printer->Print(variables_, + "int rawValue = input.readEnum();\n" + "if (!$get_mutable_bit_parser$) {\n" + " $name$_ = new java.util.ArrayList<java.lang.Integer>();\n" + " $set_mutable_bit_parser$;\n" + "}\n" + "$name$_.add(rawValue);\n"); + } else { + printer->Print( + variables_, + "int rawValue = input.readEnum();\n" + "@SuppressWarnings(\"deprecation\")\n" + "$type$ value = $type$.$for_number$(rawValue);\n" + "if (value == null) {\n" + " unknownFields.mergeVarintField($number$, rawValue);\n" + "} else {\n" + " if (!$get_mutable_bit_parser$) {\n" + " $name$_ = new java.util.ArrayList<java.lang.Integer>();\n" + " $set_mutable_bit_parser$;\n" + " }\n" + " $name$_.add(rawValue);\n" + "}\n"); + } +} + +void RepeatedImmutableEnumFieldGenerator::GenerateParsingCodeFromPacked( + io::Printer* printer) const { + // Wrap GenerateParsingCode's contents with a while loop. + + printer->Print(variables_, + "int length = input.readRawVarint32();\n" + "int oldLimit = input.pushLimit(length);\n" + "while(input.getBytesUntilLimit() > 0) {\n"); + printer->Indent(); + + GenerateParsingCode(printer); + + printer->Outdent(); + printer->Print(variables_, + "}\n" + "input.popLimit(oldLimit);\n"); +} + +void RepeatedImmutableEnumFieldGenerator::GenerateParsingDoneCode( + io::Printer* printer) const { + printer->Print( + variables_, + "if ($get_mutable_bit_parser$) {\n" + " $name$_ = java.util.Collections.unmodifiableList($name$_);\n" + "}\n"); +} + +void RepeatedImmutableEnumFieldGenerator::GenerateSerializationCode( + io::Printer* printer) const { + if (descriptor_->is_packed()) { + printer->Print(variables_, + "if (get$capitalized_name$List().size() > 0) {\n" + " output.writeUInt32NoTag($tag$);\n" + " output.writeUInt32NoTag($name$MemoizedSerializedSize);\n" + "}\n" + "for (int i = 0; i < $name$_.size(); i++) {\n" + " output.writeEnumNoTag($name$_.get(i));\n" + "}\n"); + } else { + printer->Print(variables_, + "for (int i = 0; i < $name$_.size(); i++) {\n" + " output.writeEnum($number$, $name$_.get(i));\n" + "}\n"); + } +} + +void RepeatedImmutableEnumFieldGenerator::GenerateSerializedSizeCode( + io::Printer* printer) const { + printer->Print(variables_, + "{\n" + " int dataSize = 0;\n"); + printer->Indent(); + + printer->Print(variables_, + "for (int i = 0; i < $name$_.size(); i++) {\n" + " dataSize += com.google.protobuf.CodedOutputStream\n" + " .computeEnumSizeNoTag($name$_.get(i));\n" + "}\n"); + printer->Print("size += dataSize;\n"); + if (descriptor_->is_packed()) { + printer->Print(variables_, + "if (!get$capitalized_name$List().isEmpty()) {" + " size += $tag_size$;\n" + " size += com.google.protobuf.CodedOutputStream\n" + " .computeUInt32SizeNoTag(dataSize);\n" + "}"); + } else { + printer->Print(variables_, "size += $tag_size$ * $name$_.size();\n"); + } + + // cache the data size for packed fields. + if (descriptor_->is_packed()) { + printer->Print(variables_, "$name$MemoizedSerializedSize = dataSize;\n"); + } + + printer->Outdent(); + printer->Print("}\n"); +} + +void RepeatedImmutableEnumFieldGenerator::GenerateEqualsCode( + io::Printer* printer) const { + printer->Print(variables_, + "if (!$name$_.equals(other.$name$_)) return false;\n"); +} + +void RepeatedImmutableEnumFieldGenerator::GenerateHashCode( + io::Printer* printer) const { + printer->Print(variables_, + "if (get$capitalized_name$Count() > 0) {\n" + " hash = (37 * hash) + $constant_name$;\n" + " hash = (53 * hash) + $name$_.hashCode();\n" + "}\n"); +} + +void RepeatedImmutableEnumFieldGenerator::GenerateKotlinDslMembers( + io::Printer* printer) const { + printer->Print( + variables_, + "/**\n" + " * An uninstantiable, behaviorless type to represent the field in\n" + " * generics.\n" + " */\n" + "@kotlin.OptIn" + "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n" + "public class ${$$kt_capitalized_name$Proxy$}$ private constructor()" + " : com.google.protobuf.kotlin.DslProxy()\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$kt_deprecation$ public val $kt_name$: " + "com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>\n" + " @kotlin.jvm.JvmSynthetic\n" + " get() = com.google.protobuf.kotlin.DslList(\n" + " $kt_dsl_builder$.${$get$capitalized_name$List$}$()\n" + " )\n"); + + WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, + /* builder */ false); + printer->Print(variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"add$kt_capitalized_name$\")\n" + "public fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "add(value: $kt_type$) {\n" + " $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n" + "}"); + + WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, + /* builder */ false); + printer->Print(variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"plusAssign$kt_capitalized_name$\")\n" + "@Suppress(\"NOTHING_TO_INLINE\")\n" + "public inline operator fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "plusAssign(value: $kt_type$) {\n" + " add(value)\n" + "}"); + + WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, + /* builder */ false); + printer->Print(variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"addAll$kt_capitalized_name$\")\n" + "public fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "addAll(values: kotlin.collections.Iterable<$kt_type$>) {\n" + " $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n" + "}"); + + WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, + /* builder */ false); + printer->Print( + variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"plusAssignAll$kt_capitalized_name$\")\n" + "@Suppress(\"NOTHING_TO_INLINE\")\n" + "public inline operator fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "plusAssign(values: kotlin.collections.Iterable<$kt_type$>) {\n" + " addAll(values)\n" + "}"); + + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER, + /* builder */ false); + printer->Print( + variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"set$kt_capitalized_name$\")\n" + "public operator fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "set(index: kotlin.Int, value: $kt_type$) {\n" + " $kt_dsl_builder$.${$set$capitalized_name$$}$(index, value)\n" + "}"); + + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ false); + printer->Print(variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"clear$kt_capitalized_name$\")\n" + "public fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "clear() {\n" + " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n" + "}"); +} + +std::string RepeatedImmutableEnumFieldGenerator::GetBoxedType() const { + return name_resolver_->GetImmutableClassName(descriptor_->enum_type()); +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_field.h new file mode 100644 index 00000000..1e88bbf3 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_field.h @@ -0,0 +1,161 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_H__ + +#include <map> +#include <string> +#include <compiler/java/java_field.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { +class Context; // context.h +class ClassNameResolver; // name_resolver.h +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +class ImmutableEnumFieldGenerator : public ImmutableFieldGenerator { + public: + explicit ImmutableEnumFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, int builderBitIndex, + Context* context); + ~ImmutableEnumFieldGenerator() override; + + // implements ImmutableFieldGenerator + // --------------------------------------- + int GetNumBitsForMessage() const override; + int GetNumBitsForBuilder() const override; + void GenerateInterfaceMembers(io::Printer* printer) const override; + void GenerateMembers(io::Printer* printer) const override; + void GenerateBuilderMembers(io::Printer* printer) const override; + void GenerateInitializationCode(io::Printer* printer) const override; + void GenerateBuilderClearCode(io::Printer* printer) const override; + void GenerateMergingCode(io::Printer* printer) const override; + void GenerateBuildingCode(io::Printer* printer) const override; + void GenerateParsingCode(io::Printer* printer) const override; + void GenerateParsingDoneCode(io::Printer* printer) const override; + void GenerateSerializationCode(io::Printer* printer) const override; + void GenerateSerializedSizeCode(io::Printer* printer) const override; + void GenerateFieldBuilderInitializationCode( + io::Printer* printer) const override; + void GenerateEqualsCode(io::Printer* printer) const override; + void GenerateHashCode(io::Printer* printer) const override; + void GenerateKotlinDslMembers(io::Printer* printer) const override; + + std::string GetBoxedType() const override; + + protected: + const FieldDescriptor* descriptor_; + std::map<std::string, std::string> variables_; + ClassNameResolver* name_resolver_; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableEnumFieldGenerator); +}; + +class ImmutableEnumOneofFieldGenerator : public ImmutableEnumFieldGenerator { + public: + ImmutableEnumOneofFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, int builderBitIndex, + Context* context); + ~ImmutableEnumOneofFieldGenerator(); + + void GenerateMembers(io::Printer* printer) const override; + void GenerateBuilderMembers(io::Printer* printer) const override; + void GenerateMergingCode(io::Printer* printer) const override; + void GenerateBuildingCode(io::Printer* printer) const override; + void GenerateParsingCode(io::Printer* printer) const override; + void GenerateSerializationCode(io::Printer* printer) const override; + void GenerateSerializedSizeCode(io::Printer* printer) const override; + void GenerateEqualsCode(io::Printer* printer) const override; + void GenerateHashCode(io::Printer* printer) const override; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableEnumOneofFieldGenerator); +}; + +class RepeatedImmutableEnumFieldGenerator : public ImmutableFieldGenerator { + public: + explicit RepeatedImmutableEnumFieldGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, + int builderBitIndex, Context* context); + ~RepeatedImmutableEnumFieldGenerator() override; + + // implements ImmutableFieldGenerator --------------------------------------- + int GetNumBitsForMessage() const override; + int GetNumBitsForBuilder() const override; + void GenerateInterfaceMembers(io::Printer* printer) const override; + void GenerateMembers(io::Printer* printer) const override; + void GenerateBuilderMembers(io::Printer* printer) const override; + void GenerateInitializationCode(io::Printer* printer) const override; + void GenerateBuilderClearCode(io::Printer* printer) const override; + void GenerateMergingCode(io::Printer* printer) const override; + void GenerateBuildingCode(io::Printer* printer) const override; + void GenerateParsingCode(io::Printer* printer) const override; + void GenerateParsingCodeFromPacked(io::Printer* printer) const override; + void GenerateParsingDoneCode(io::Printer* printer) const override; + void GenerateSerializationCode(io::Printer* printer) const override; + void GenerateSerializedSizeCode(io::Printer* printer) const override; + void GenerateFieldBuilderInitializationCode( + io::Printer* printer) const override; + void GenerateEqualsCode(io::Printer* printer) const override; + void GenerateHashCode(io::Printer* printer) const override; + void GenerateKotlinDslMembers(io::Printer* printer) const override; + + std::string GetBoxedType() const override; + + private: + const FieldDescriptor* descriptor_; + std::map<std::string, std::string> variables_; + ClassNameResolver* name_resolver_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableEnumFieldGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_H__ diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_field_lite.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_field_lite.cc new file mode 100644 index 00000000..ffc28ef0 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_field_lite.cc @@ -0,0 +1,918 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <compiler/java/java_enum_field_lite.h> + +#include <cstdint> +#include <map> +#include <string> + +#include <stubs/logging.h> +#include <stubs/common.h> +#include <compiler/java/java_context.h> +#include <compiler/java/java_doc_comment.h> +#include <compiler/java/java_helpers.h> +#include <compiler/java/java_name_resolver.h> +#include <io/printer.h> +#include <wire_format.h> +#include <stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +namespace { +bool EnableExperimentalRuntimeForLite() { +#ifdef PROTOBUF_EXPERIMENT + return PROTOBUF_EXPERIMENT; +#else // PROTOBUF_EXPERIMENT + return false; +#endif // !PROTOBUF_EXPERIMENT +} + +void SetEnumVariables(const FieldDescriptor* descriptor, int messageBitIndex, + int builderBitIndex, const FieldGeneratorInfo* info, + ClassNameResolver* name_resolver, + std::map<std::string, std::string>* variables) { + SetCommonFieldVariables(descriptor, info, variables); + + (*variables)["type"] = + name_resolver->GetImmutableClassName(descriptor->enum_type()); + (*variables)["kt_type"] = (*variables)["type"]; + (*variables)["mutable_type"] = + name_resolver->GetMutableClassName(descriptor->enum_type()); + (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver); + (*variables)["default_number"] = + StrCat(descriptor->default_value_enum()->number()); + (*variables)["tag"] = StrCat( + static_cast<int32_t>(internal::WireFormat::MakeTag(descriptor))); + (*variables)["tag_size"] = StrCat( + internal::WireFormat::TagSize(descriptor->number(), GetType(descriptor))); + // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported + // by the proto compiler + (*variables)["deprecation"] = + descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; + (*variables)["kt_deprecation"] = + descriptor->options().deprecated() + ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] + + " is deprecated\") " + : ""; + (*variables)["required"] = descriptor->is_required() ? "true" : "false"; + + if (HasHasbit(descriptor)) { + // For singular messages and builders, one bit is used for the hasField bit. + (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); + + // Note that these have a trailing ";". + (*variables)["set_has_field_bit_message"] = + GenerateSetBit(messageBitIndex) + ";"; + (*variables)["clear_has_field_bit_message"] = + GenerateClearBit(messageBitIndex) + ";"; + + (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex); + } else { + (*variables)["set_has_field_bit_message"] = ""; + (*variables)["clear_has_field_bit_message"] = ""; + + (*variables)["is_field_present_message"] = + (*variables)["name"] + "_ != " + (*variables)["default"] + + ".getNumber()"; + } + + (*variables)["get_has_field_bit_from_local"] = + GenerateGetBitFromLocal(builderBitIndex); + (*variables)["set_has_field_bit_to_local"] = + GenerateSetBitToLocal(messageBitIndex); + + if (SupportUnknownEnumValue(descriptor->file())) { + (*variables)["unknown"] = (*variables)["type"] + ".UNRECOGNIZED"; + } else { + (*variables)["unknown"] = (*variables)["default"]; + } + + // We use `x.getClass()` as a null check because it generates less bytecode + // than an `if (x == null) { throw ... }` statement. + (*variables)["null_check"] = "value.getClass();\n"; +} + +} // namespace + +// =================================================================== + +ImmutableEnumFieldLiteGenerator::ImmutableEnumFieldLiteGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, Context* context) + : descriptor_(descriptor), + messageBitIndex_(messageBitIndex), + context_(context), + name_resolver_(context->GetNameResolver()) { + SetEnumVariables(descriptor, messageBitIndex, 0, + context->GetFieldGeneratorInfo(descriptor), name_resolver_, + &variables_); +} + +ImmutableEnumFieldLiteGenerator::~ImmutableEnumFieldLiteGenerator() {} + +int ImmutableEnumFieldLiteGenerator::GetNumBitsForMessage() const { + return HasHasbit(descriptor_) ? 1 : 0; +} + +void ImmutableEnumFieldLiteGenerator::GenerateInterfaceMembers( + io::Printer* printer) const { + if (HasHazzer(descriptor_)) { + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print(variables_, + "$deprecation$boolean has$capitalized_name$();\n"); + } + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, + "$deprecation$int get$capitalized_name$Value();\n"); + } + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n"); +} + +void ImmutableEnumFieldLiteGenerator::GenerateMembers( + io::Printer* printer) const { + printer->Print(variables_, "private int $name$_;\n"); + PrintExtraFieldInfo(variables_, printer); + if (HasHazzer(descriptor_)) { + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return $get_has_field_bit_message$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n" + " return $name$_;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" + " $type$ result = $type$.forNumber($name$_);\n" + " return result == null ? $unknown$ : result;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + // Generate private setters for the builder to proxy into. + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER); + printer->Print(variables_, + "private void set$capitalized_name$Value(int value) {\n" + " $set_has_field_bit_message$" + " $name$_ = value;\n" + "}\n"); + } + WriteFieldAccessorDocComment(printer, descriptor_, SETTER); + printer->Print(variables_, + "private void set$capitalized_name$($type$ value) {\n" + " $name$_ = value.getNumber();\n" + " $set_has_field_bit_message$\n" + "}\n"); + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER); + printer->Print(variables_, + "private void clear$capitalized_name$() {\n" + " $clear_has_field_bit_message$\n" + " $name$_ = $default_number$;\n" + "}\n"); +} + +void ImmutableEnumFieldLiteGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + if (HasHazzer(descriptor_)) { + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return instance.has$capitalized_name$();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n" + " return instance.get$capitalized_name$Value();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, SETTER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder " + "${$set$capitalized_name$Value$}$(int value) {\n" + " copyOnWrite();\n" + " instance.set$capitalized_name$Value(value);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" + " return instance.get$capitalized_name$();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder " + "${$set$capitalized_name$$}$($type$ value) {\n" + " copyOnWrite();\n" + " instance.set$capitalized_name$(value);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ true); + printer->Print( + variables_, + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" + " copyOnWrite();\n" + " instance.clear$capitalized_name$();\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +void ImmutableEnumFieldLiteGenerator::GenerateKotlinDslMembers( + io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$kt_deprecation$public var $kt_name$: $kt_type$\n" + " @JvmName(\"${$get$kt_capitalized_name$$}$\")\n" + " get() = $kt_dsl_builder$.${$get$capitalized_name$$}$()\n" + " @JvmName(\"${$set$kt_capitalized_name$$}$\")\n" + " set(value) {\n" + " $kt_dsl_builder$.${$set$capitalized_name$$}$(value)\n" + " }\n"); + + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ false); + printer->Print(variables_, + "public fun ${$clear$kt_capitalized_name$$}$() {\n" + " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n" + "}\n"); + + if (HasHazzer(descriptor_)) { + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print( + variables_, + "public fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n" + " return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n" + "}\n"); + } +} + +void ImmutableEnumFieldLiteGenerator::GenerateInitializationCode( + io::Printer* printer) const { + if (!IsDefaultValueJavaDefault(descriptor_)) { + printer->Print(variables_, "$name$_ = $default_number$;\n"); + } +} + +void ImmutableEnumFieldLiteGenerator::GenerateFieldInfo( + io::Printer* printer, std::vector<uint16_t>* output) const { + WriteIntToUtf16CharSequence(descriptor_->number(), output); + WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_), + output); + if (HasHasbit(descriptor_)) { + WriteIntToUtf16CharSequence(messageBitIndex_, output); + } + printer->Print(variables_, "\"$name$_\",\n"); + if (!SupportUnknownEnumValue((descriptor_))) { + PrintEnumVerifierLogic(printer, descriptor_, variables_, + /*var_name=*/"$type$", + /*terminating_string=*/",\n", + /*enforce_lite=*/context_->EnforceLite()); + } +} + +std::string ImmutableEnumFieldLiteGenerator::GetBoxedType() const { + return name_resolver_->GetImmutableClassName(descriptor_->enum_type()); +} + +// =================================================================== + +ImmutableEnumOneofFieldLiteGenerator::ImmutableEnumOneofFieldLiteGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, Context* context) + : ImmutableEnumFieldLiteGenerator(descriptor, messageBitIndex, context) { + const OneofGeneratorInfo* info = + context->GetOneofGeneratorInfo(descriptor->containing_oneof()); + SetCommonOneofVariables(descriptor, info, &variables_); +} + +ImmutableEnumOneofFieldLiteGenerator::~ImmutableEnumOneofFieldLiteGenerator() {} + +void ImmutableEnumOneofFieldLiteGenerator::GenerateMembers( + io::Printer* printer) const { + PrintExtraFieldInfo(variables_, printer); + GOOGLE_DCHECK(HasHazzer(descriptor_)); + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return $has_oneof_case_message$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n" + " if ($has_oneof_case_message$) {\n" + " return (java.lang.Integer) $oneof_name$_;\n" + " }\n" + " return $default_number$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" + " if ($has_oneof_case_message$) {\n" + " $type$ result = $type$.forNumber((java.lang.Integer) " + "$oneof_name$_);\n" + " return result == null ? $unknown$ : result;\n" + " }\n" + " return $default$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + // Generate private setters for the builder to proxy into. + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER); + printer->Print(variables_, + "private void set$capitalized_name$Value(int value) {\n" + " $set_oneof_case_message$;\n" + " $oneof_name$_ = value;\n" + "}\n"); + } + WriteFieldAccessorDocComment(printer, descriptor_, SETTER); + printer->Print(variables_, + "private void set$capitalized_name$($type$ value) {\n" + " $oneof_name$_ = value.getNumber();\n" + " $set_oneof_case_message$;\n" + "}\n"); + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER); + printer->Print(variables_, + "private void clear$capitalized_name$() {\n" + " if ($has_oneof_case_message$) {\n" + " $clear_oneof_case_message$;\n" + " $oneof_name$_ = null;\n" + " }\n" + "}\n"); +} + +void ImmutableEnumOneofFieldLiteGenerator::GenerateFieldInfo( + io::Printer* printer, std::vector<uint16_t>* output) const { + WriteIntToUtf16CharSequence(descriptor_->number(), output); + WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_), + output); + WriteIntToUtf16CharSequence(descriptor_->containing_oneof()->index(), output); + if (!SupportUnknownEnumValue(descriptor_)) { + PrintEnumVerifierLogic(printer, descriptor_, variables_, + /*var_name=*/"$type$", + /*terminating_string=*/",\n", + /*enforce_lite=*/context_->EnforceLite()); + } +} + +void ImmutableEnumOneofFieldLiteGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + GOOGLE_DCHECK(HasHazzer(descriptor_)); + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return instance.has$capitalized_name$();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n" + " return instance.get$capitalized_name$Value();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder " + "${$set$capitalized_name$Value$}$(int value) {\n" + " copyOnWrite();\n" + " instance.set$capitalized_name$Value(value);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" + " return instance.get$capitalized_name$();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, SETTER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder " + "${$set$capitalized_name$$}$($type$ value) {\n" + " copyOnWrite();\n" + " instance.set$capitalized_name$(value);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ true); + printer->Print( + variables_, + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" + " copyOnWrite();\n" + " instance.clear$capitalized_name$();\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +// =================================================================== + +RepeatedImmutableEnumFieldLiteGenerator:: + RepeatedImmutableEnumFieldLiteGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + Context* context) + : descriptor_(descriptor), + context_(context), + name_resolver_(context->GetNameResolver()) { + SetEnumVariables(descriptor, messageBitIndex, 0, + context->GetFieldGeneratorInfo(descriptor), name_resolver_, + &variables_); +} + +RepeatedImmutableEnumFieldLiteGenerator:: + ~RepeatedImmutableEnumFieldLiteGenerator() {} + +int RepeatedImmutableEnumFieldLiteGenerator::GetNumBitsForMessage() const { + return 0; +} + +void RepeatedImmutableEnumFieldLiteGenerator::GenerateInterfaceMembers( + io::Printer* printer) const { + WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER); + printer->Print( + variables_, + "$deprecation$java.util.List<$type$> get$capitalized_name$List();\n"); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT); + printer->Print(variables_, + "$deprecation$int get$capitalized_name$Count();\n"); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER); + printer->Print(variables_, + "$deprecation$$type$ get$capitalized_name$(int index);\n"); + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_GETTER); + printer->Print(variables_, + "$deprecation$java.util.List<java.lang.Integer>\n" + "get$capitalized_name$ValueList();\n"); + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, + LIST_INDEXED_GETTER); + printer->Print(variables_, + "$deprecation$int get$capitalized_name$Value(int index);\n"); + } +} + +void RepeatedImmutableEnumFieldLiteGenerator::GenerateMembers( + io::Printer* printer) const { + printer->Print( + variables_, + "private com.google.protobuf.Internal.IntList $name$_;\n" + "private static final " + "com.google.protobuf.Internal.ListAdapter.Converter<\n" + " java.lang.Integer, $type$> $name$_converter_ =\n" + " new com.google.protobuf.Internal.ListAdapter.Converter<\n" + " java.lang.Integer, $type$>() {\n" + " @java.lang.Override\n" + " public $type$ convert(java.lang.Integer from) {\n" + " $type$ result = $type$.forNumber(from);\n" + " return result == null ? $unknown$ : result;\n" + " }\n" + " };\n"); + PrintExtraFieldInfo(variables_, printer); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public java.util.List<$type$> " + "${$get$capitalized_name$List$}$() {\n" + " return new com.google.protobuf.Internal.ListAdapter<\n" + " java.lang.Integer, $type$>($name$_, $name$_converter_);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" + " return $name$_.size();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER); + printer->Print( + variables_, + // NB: Do not use the "$name$_converter_" field; the usage of generics + // (and requisite upcasts to Object) prevent optimizations. Even + // without any optimizations, the below code is cheaper because it + // avoids boxing an int and a checkcast from the generics. + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" + " $type$ result = $type$.forNumber($name$_.getInt(index));\n" + " return result == null ? $unknown$ : result;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public java.util.List<java.lang.Integer>\n" + "${$get$capitalized_name$ValueList$}$() {\n" + " return $name$_;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, + LIST_INDEXED_GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public int " + "${$get$capitalized_name$Value$}$(int index) {\n" + " return $name$_.getInt(index);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } + + if (!EnableExperimentalRuntimeForLite() && descriptor_->is_packed() && + context_->HasGeneratedMethods(descriptor_->containing_type())) { + printer->Print(variables_, "private int $name$MemoizedSerializedSize;\n"); + } + + // Generate private setters for the builder to proxy into. + printer->Print( + variables_, + "private void ensure$capitalized_name$IsMutable() {\n" + // Use a temporary to avoid a redundant iget-object. + " com.google.protobuf.Internal.IntList tmp = $name$_;\n" + " if (!tmp.isModifiable()) {\n" + " $name$_ =\n" + " com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);\n" + " }\n" + "}\n"); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER); + printer->Print(variables_, + "private void set$capitalized_name$(\n" + " int index, $type$ value) {\n" + " $null_check$" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.setInt(index, value.getNumber());\n" + "}\n"); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER); + printer->Print(variables_, + "private void add$capitalized_name$($type$ value) {\n" + " $null_check$" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.addInt(value.getNumber());\n" + "}\n"); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER); + printer->Print(variables_, + "private void addAll$capitalized_name$(\n" + " java.lang.Iterable<? extends $type$> values) {\n" + " ensure$capitalized_name$IsMutable();\n" + " for ($type$ value : values) {\n" + " $name$_.addInt(value.getNumber());\n" + " }\n" + "}\n"); + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER); + printer->Print(variables_, + "private void clear$capitalized_name$() {\n" + " $name$_ = emptyIntList();\n" + "}\n"); + + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER); + printer->Print(variables_, + "private void set$capitalized_name$Value(\n" + " int index, int value) {\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.setInt(index, value);\n" + "}\n"); + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_ADDER); + printer->Print(variables_, + "private void add$capitalized_name$Value(int value) {\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.addInt(value);\n" + "}\n"); + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, + LIST_MULTI_ADDER); + printer->Print(variables_, + "private void addAll$capitalized_name$Value(\n" + " java.lang.Iterable<java.lang.Integer> values) {\n" + " ensure$capitalized_name$IsMutable();\n" + " for (int value : values) {\n" + " $name$_.addInt(value);\n" + " }\n" + "}\n"); + } +} + +void RepeatedImmutableEnumFieldLiteGenerator::GenerateFieldInfo( + io::Printer* printer, std::vector<uint16_t>* output) const { + WriteIntToUtf16CharSequence(descriptor_->number(), output); + WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_), + output); + printer->Print(variables_, "\"$name$_\",\n"); + if (!SupportUnknownEnumValue(descriptor_->file())) { + PrintEnumVerifierLogic(printer, descriptor_, variables_, + /*var_name=*/"$type$", + /*terminating_string=*/",\n", + /*enforce_lite=*/context_->EnforceLite()); + } +} + +void RepeatedImmutableEnumFieldLiteGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public java.util.List<$type$> " + "${$get$capitalized_name$List$}$() {\n" + " return instance.get$capitalized_name$List();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" + " return instance.get$capitalized_name$Count();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" + " return instance.get$capitalized_name$(index);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" + " int index, $type$ value) {\n" + " copyOnWrite();\n" + " instance.set$capitalized_name$(index, value);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder " + "${$add$capitalized_name$$}$($type$ value) {\n" + " copyOnWrite();\n" + " instance.add$capitalized_name$(value);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n" + " java.lang.Iterable<? extends $type$> values) {\n" + " copyOnWrite();\n" + " instance.addAll$capitalized_name$(values);" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ true); + printer->Print( + variables_, + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" + " copyOnWrite();\n" + " instance.clear$capitalized_name$();\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public java.util.List<java.lang.Integer>\n" + "${$get$capitalized_name$ValueList$}$() {\n" + " return java.util.Collections.unmodifiableList(\n" + " instance.get$capitalized_name$ValueList());\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, + LIST_INDEXED_GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public int " + "${$get$capitalized_name$Value$}$(int index) {\n" + " return instance.get$capitalized_name$Value(index);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, + LIST_INDEXED_SETTER, + /* builder */ true); + printer->Print( + variables_, + "$deprecation$public Builder ${$set$capitalized_name$Value$}$(\n" + " int index, int value) {\n" + " copyOnWrite();\n" + " instance.set$capitalized_name$Value(index, value);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_ADDER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder " + "${$add$capitalized_name$Value$}$(int value) {\n" + " instance.add$capitalized_name$Value(value);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldEnumValueAccessorDocComment(printer, descriptor_, + LIST_MULTI_ADDER, + /* builder */ true); + printer->Print( + variables_, + "$deprecation$public Builder ${$addAll$capitalized_name$Value$}$(\n" + " java.lang.Iterable<java.lang.Integer> values) {\n" + " copyOnWrite();\n" + " instance.addAll$capitalized_name$Value(values);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } +} + +void RepeatedImmutableEnumFieldLiteGenerator::GenerateInitializationCode( + io::Printer* printer) const { + printer->Print(variables_, "$name$_ = emptyIntList();\n"); +} + +void RepeatedImmutableEnumFieldLiteGenerator::GenerateKotlinDslMembers( + io::Printer* printer) const { + printer->Print( + variables_, + "/**\n" + " * An uninstantiable, behaviorless type to represent the field in\n" + " * generics.\n" + " */\n" + "@kotlin.OptIn" + "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n" + "public class ${$$kt_capitalized_name$Proxy$}$ private constructor()" + " : com.google.protobuf.kotlin.DslProxy()\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$kt_deprecation$ public val $kt_name$: " + "com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>\n" + " @kotlin.jvm.JvmSynthetic\n" + " get() = com.google.protobuf.kotlin.DslList(\n" + " $kt_dsl_builder$.${$get$capitalized_name$List$}$()\n" + " )\n"); + + WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, + /* builder */ false); + printer->Print(variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"add$kt_capitalized_name$\")\n" + "public fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "add(value: $kt_type$) {\n" + " $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n" + "}"); + + WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, + /* builder */ false); + printer->Print(variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"plusAssign$kt_capitalized_name$\")\n" + "@Suppress(\"NOTHING_TO_INLINE\")\n" + "public inline operator fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "plusAssign(value: $kt_type$) {\n" + " add(value)\n" + "}"); + + WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, + /* builder */ false); + printer->Print(variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"addAll$kt_capitalized_name$\")\n" + "public fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "addAll(values: kotlin.collections.Iterable<$kt_type$>) {\n" + " $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n" + "}"); + + WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, + /* builder */ false); + printer->Print( + variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"plusAssignAll$kt_capitalized_name$\")\n" + "@Suppress(\"NOTHING_TO_INLINE\")\n" + "public inline operator fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "plusAssign(values: kotlin.collections.Iterable<$kt_type$>) {\n" + " addAll(values)\n" + "}"); + + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER, + /* builder */ false); + printer->Print( + variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"set$kt_capitalized_name$\")\n" + "public operator fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "set(index: kotlin.Int, value: $kt_type$) {\n" + " $kt_dsl_builder$.${$set$capitalized_name$$}$(index, value)\n" + "}"); + + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ false); + printer->Print(variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"clear$kt_capitalized_name$\")\n" + "public fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "clear() {\n" + " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n" + "}"); +} + +std::string RepeatedImmutableEnumFieldLiteGenerator::GetBoxedType() const { + return name_resolver_->GetImmutableClassName(descriptor_->enum_type()); +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_field_lite.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_field_lite.h new file mode 100644 index 00000000..8073f393 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_field_lite.h @@ -0,0 +1,140 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_LITE_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_LITE_H__ + +#include <cstdint> +#include <map> +#include <string> + +#include <compiler/java/java_field.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { +class Context; // context.h +class ClassNameResolver; // name_resolver.h +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +class ImmutableEnumFieldLiteGenerator : public ImmutableFieldLiteGenerator { + public: + explicit ImmutableEnumFieldLiteGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + Context* context); + ~ImmutableEnumFieldLiteGenerator() override; + + // implements ImmutableFieldLiteGenerator + // ------------------------------------ + int GetNumBitsForMessage() const override; + void GenerateInterfaceMembers(io::Printer* printer) const override; + void GenerateMembers(io::Printer* printer) const override; + void GenerateBuilderMembers(io::Printer* printer) const override; + void GenerateInitializationCode(io::Printer* printer) const override; + void GenerateFieldInfo(io::Printer* printer, + std::vector<uint16_t>* output) const override; + void GenerateKotlinDslMembers(io::Printer* printer) const override; + + std::string GetBoxedType() const override; + + protected: + const FieldDescriptor* descriptor_; + std::map<std::string, std::string> variables_; + const int messageBitIndex_; + Context* context_; + ClassNameResolver* name_resolver_; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableEnumFieldLiteGenerator); +}; + +class ImmutableEnumOneofFieldLiteGenerator + : public ImmutableEnumFieldLiteGenerator { + public: + ImmutableEnumOneofFieldLiteGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, Context* context); + ~ImmutableEnumOneofFieldLiteGenerator() override; + + void GenerateMembers(io::Printer* printer) const override; + void GenerateBuilderMembers(io::Printer* printer) const override; + void GenerateFieldInfo(io::Printer* printer, + std::vector<uint16_t>* output) const override; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableEnumOneofFieldLiteGenerator); +}; + +class RepeatedImmutableEnumFieldLiteGenerator + : public ImmutableFieldLiteGenerator { + public: + explicit RepeatedImmutableEnumFieldLiteGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, Context* context); + ~RepeatedImmutableEnumFieldLiteGenerator() override; + + // implements ImmutableFieldLiteGenerator ------------------------------------ + int GetNumBitsForMessage() const override; + void GenerateInterfaceMembers(io::Printer* printer) const override; + void GenerateMembers(io::Printer* printer) const override; + void GenerateBuilderMembers(io::Printer* printer) const override; + void GenerateInitializationCode(io::Printer* printer) const override; + void GenerateFieldInfo(io::Printer* printer, + std::vector<uint16_t>* output) const override; + void GenerateKotlinDslMembers(io::Printer* printer) const override; + + std::string GetBoxedType() const override; + + private: + const FieldDescriptor* descriptor_; + std::map<std::string, std::string> variables_; + Context* context_; + ClassNameResolver* name_resolver_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableEnumFieldLiteGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_FIELD_LITE_H__ diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_lite.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_lite.cc new file mode 100644 index 00000000..7cfad624 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_lite.cc @@ -0,0 +1,235 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <map> +#include <string> + +#include <compiler/java/java_context.h> +#include <compiler/java/java_doc_comment.h> +#include <compiler/java/java_enum_lite.h> +#include <compiler/java/java_helpers.h> +#include <compiler/java/java_name_resolver.h> +#include <descriptor.pb.h> +#include <io/printer.h> +#include <stubs/strutil.h> +#include <stubs/map_util.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +EnumLiteGenerator::EnumLiteGenerator(const EnumDescriptor* descriptor, + bool immutable_api, Context* context) + : descriptor_(descriptor), + immutable_api_(immutable_api), + context_(context), + name_resolver_(context->GetNameResolver()) { + for (int i = 0; i < descriptor_->value_count(); i++) { + const EnumValueDescriptor* value = descriptor_->value(i); + const EnumValueDescriptor* canonical_value = + descriptor_->FindValueByNumber(value->number()); + + if (value == canonical_value) { + canonical_values_.push_back(value); + } else { + Alias alias; + alias.value = value; + alias.canonical_value = canonical_value; + aliases_.push_back(alias); + } + } +} + +EnumLiteGenerator::~EnumLiteGenerator() {} + +void EnumLiteGenerator::Generate(io::Printer* printer) { + WriteEnumDocComment(printer, descriptor_); + MaybePrintGeneratedAnnotation(context_, printer, descriptor_, immutable_api_); + printer->Print( + "$deprecation$public enum $classname$\n" + " implements com.google.protobuf.Internal.EnumLite {\n", + "classname", descriptor_->name(), "deprecation", + descriptor_->options().deprecated() ? "@java.lang.Deprecated " : ""); + printer->Annotate("classname", descriptor_); + printer->Indent(); + + for (int i = 0; i < canonical_values_.size(); i++) { + std::map<std::string, std::string> vars; + vars["name"] = canonical_values_[i]->name(); + vars["number"] = StrCat(canonical_values_[i]->number()); + WriteEnumValueDocComment(printer, canonical_values_[i]); + if (canonical_values_[i]->options().deprecated()) { + printer->Print("@java.lang.Deprecated\n"); + } + printer->Print(vars, "$name$($number$),\n"); + printer->Annotate("name", canonical_values_[i]); + } + + if (SupportUnknownEnumValue(descriptor_->file())) { + printer->Print("${$UNRECOGNIZED$}$(-1),\n", "{", "", "}", ""); + printer->Annotate("{", "}", descriptor_); + } + + printer->Print( + ";\n" + "\n"); + + // ----------------------------------------------------------------- + + for (int i = 0; i < aliases_.size(); i++) { + std::map<std::string, std::string> vars; + vars["classname"] = descriptor_->name(); + vars["name"] = aliases_[i].value->name(); + vars["canonical_name"] = aliases_[i].canonical_value->name(); + WriteEnumValueDocComment(printer, aliases_[i].value); + printer->Print( + vars, "public static final $classname$ $name$ = $canonical_name$;\n"); + printer->Annotate("name", aliases_[i].value); + } + + for (int i = 0; i < descriptor_->value_count(); i++) { + std::map<std::string, std::string> vars; + vars["name"] = descriptor_->value(i)->name(); + vars["number"] = StrCat(descriptor_->value(i)->number()); + vars["{"] = ""; + vars["}"] = ""; + vars["deprecation"] = descriptor_->value(i)->options().deprecated() + ? "@java.lang.Deprecated " + : ""; + WriteEnumValueDocComment(printer, descriptor_->value(i)); + printer->Print(vars, + "$deprecation$public static final int ${$$name$_VALUE$}$ = " + "$number$;\n"); + printer->Annotate("{", "}", descriptor_->value(i)); + } + printer->Print("\n"); + + // ----------------------------------------------------------------- + + printer->Print( + "\n" + "@java.lang.Override\n" + "public final int getNumber() {\n"); + if (SupportUnknownEnumValue(descriptor_->file())) { + printer->Print( + " if (this == UNRECOGNIZED) {\n" + " throw new java.lang.IllegalArgumentException(\n" + " \"Can't get the number of an unknown enum value.\");\n" + " }\n"); + } + printer->Print( + " return value;\n" + "}\n" + "\n" + "/**\n" + " * @param value The number of the enum to look for.\n" + " * @return The enum associated with the given number.\n" + " * @deprecated Use {@link #forNumber(int)} instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "public static $classname$ valueOf(int value) {\n" + " return forNumber(value);\n" + "}\n" + "\n" + "public static $classname$ forNumber(int value) {\n" + " switch (value) {\n", + "classname", descriptor_->name()); + printer->Indent(); + printer->Indent(); + + for (int i = 0; i < canonical_values_.size(); i++) { + printer->Print("case $number$: return $name$;\n", "name", + canonical_values_[i]->name(), "number", + StrCat(canonical_values_[i]->number())); + } + + printer->Outdent(); + printer->Outdent(); + printer->Print( + " default: return null;\n" + " }\n" + "}\n" + "\n" + "public static com.google.protobuf.Internal.EnumLiteMap<$classname$>\n" + " internalGetValueMap() {\n" + " return internalValueMap;\n" + "}\n" + "private static final com.google.protobuf.Internal.EnumLiteMap<\n" + " $classname$> internalValueMap =\n" + " new com.google.protobuf.Internal.EnumLiteMap<$classname$>() {\n" + " @java.lang.Override\n" + " public $classname$ findValueByNumber(int number) {\n" + " return $classname$.forNumber(number);\n" + " }\n" + " };\n" + "\n" + "public static com.google.protobuf.Internal.EnumVerifier \n" + " internalGetVerifier() {\n" + " return $classname$Verifier.INSTANCE;\n" + "}\n" + "\n" + "private static final class $classname$Verifier implements \n" + " com.google.protobuf.Internal.EnumVerifier { \n" + " static final com.google.protobuf.Internal.EnumVerifier " + " INSTANCE = new $classname$Verifier();\n" + " @java.lang.Override\n" + " public boolean isInRange(int number) {\n" + " return $classname$.forNumber(number) != null;\n" + " }\n" + " };\n" + "\n", + "classname", descriptor_->name()); + + printer->Print( + "private final int value;\n\n" + "private $classname$(int value) {\n", + "classname", descriptor_->name()); + printer->Print( + " this.value = value;\n" + "}\n"); + + printer->Print( + "\n" + "// @@protoc_insertion_point(enum_scope:$full_name$)\n", + "full_name", descriptor_->full_name()); + + printer->Outdent(); + printer->Print("}\n\n"); +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_lite.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_lite.h new file mode 100644 index 00000000..0b706d8e --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_enum_lite.h @@ -0,0 +1,98 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_LITE_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_LITE_H__ + +#include <string> +#include <vector> +#include <descriptor.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { +class Context; // context.h +class ClassNameResolver; // name_resolver.h +} // namespace java +} // namespace compiler +namespace io { +class Printer; // printer.h +} +} // namespace protobuf +} // namespace google + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +class EnumLiteGenerator { + public: + EnumLiteGenerator(const EnumDescriptor* descriptor, bool immutable_api, + Context* context); + ~EnumLiteGenerator(); + + void Generate(io::Printer* printer); + + private: + const EnumDescriptor* descriptor_; + + // The proto language allows multiple enum constants to have the same + // numeric value. Java, however, does not allow multiple enum constants to + // be considered equivalent. We treat the first defined constant for any + // given numeric value as "canonical" and the rest as aliases of that + // canonical value. + std::vector<const EnumValueDescriptor*> canonical_values_; + + struct Alias { + const EnumValueDescriptor* value; + const EnumValueDescriptor* canonical_value; + }; + std::vector<Alias> aliases_; + + bool immutable_api_; + + Context* context_; + ClassNameResolver* name_resolver_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumLiteGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_LITE_H__ diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_extension.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_extension.cc new file mode 100644 index 00000000..d45fd9c1 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_extension.cc @@ -0,0 +1,172 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <compiler/java/java_extension.h> + +#include <compiler/java/java_context.h> +#include <compiler/java/java_doc_comment.h> +#include <compiler/java/java_helpers.h> +#include <compiler/java/java_name_resolver.h> +#include <io/printer.h> +#include <stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +ImmutableExtensionGenerator::ImmutableExtensionGenerator( + const FieldDescriptor* descriptor, Context* context) + : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) { + if (descriptor_->extension_scope() != NULL) { + scope_ = + name_resolver_->GetImmutableClassName(descriptor_->extension_scope()); + } else { + scope_ = name_resolver_->GetImmutableClassName(descriptor_->file()); + } +} + +ImmutableExtensionGenerator::~ImmutableExtensionGenerator() {} + +// Initializes the vars referenced in the generated code templates. +void ExtensionGenerator::InitTemplateVars( + const FieldDescriptor* descriptor, const std::string& scope, bool immutable, + ClassNameResolver* name_resolver, + std::map<std::string, std::string>* vars_pointer) { + std::map<std::string, std::string>& vars = *vars_pointer; + vars["scope"] = scope; + vars["name"] = UnderscoresToCamelCaseCheckReserved(descriptor); + vars["containing_type"] = + name_resolver->GetClassName(descriptor->containing_type(), immutable); + vars["number"] = StrCat(descriptor->number()); + vars["constant_name"] = FieldConstantName(descriptor); + vars["index"] = StrCat(descriptor->index()); + vars["default"] = descriptor->is_repeated() + ? "" + : DefaultValue(descriptor, immutable, name_resolver); + vars["type_constant"] = FieldTypeName(GetType(descriptor)); + vars["packed"] = descriptor->is_packed() ? "true" : "false"; + vars["enum_map"] = "null"; + vars["prototype"] = "null"; + + JavaType java_type = GetJavaType(descriptor); + std::string singular_type; + switch (java_type) { + case JAVATYPE_MESSAGE: + singular_type = + name_resolver->GetClassName(descriptor->message_type(), immutable); + vars["prototype"] = singular_type + ".getDefaultInstance()"; + break; + case JAVATYPE_ENUM: + singular_type = + name_resolver->GetClassName(descriptor->enum_type(), immutable); + vars["enum_map"] = singular_type + ".internalGetValueMap()"; + break; + case JAVATYPE_STRING: + singular_type = "java.lang.String"; + break; + case JAVATYPE_BYTES: + singular_type = immutable ? "com.google.protobuf.ByteString" : "byte[]"; + break; + default: + singular_type = BoxedPrimitiveTypeName(java_type); + break; + } + vars["type"] = descriptor->is_repeated() + ? "java.util.List<" + singular_type + ">" + : singular_type; + vars["singular_type"] = singular_type; +} + +void ImmutableExtensionGenerator::Generate(io::Printer* printer) { + std::map<std::string, std::string> vars; + const bool kUseImmutableNames = true; + InitTemplateVars(descriptor_, scope_, kUseImmutableNames, name_resolver_, + &vars); + printer->Print(vars, "public static final int $constant_name$ = $number$;\n"); + + WriteFieldDocComment(printer, descriptor_); + if (descriptor_->extension_scope() == NULL) { + // Non-nested + printer->Print( + vars, + "public static final\n" + " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n" + " $containing_type$,\n" + " $type$> $name$ = com.google.protobuf.GeneratedMessage\n" + " .newFileScopedGeneratedExtension(\n" + " $singular_type$.class,\n" + " $prototype$);\n"); + } else { + // Nested + printer->Print( + vars, + "public static final\n" + " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n" + " $containing_type$,\n" + " $type$> $name$ = com.google.protobuf.GeneratedMessage\n" + " .newMessageScopedGeneratedExtension(\n" + " $scope$.getDefaultInstance(),\n" + " $index$,\n" + " $singular_type$.class,\n" + " $prototype$);\n"); + } + printer->Annotate("name", descriptor_); +} + +int ImmutableExtensionGenerator::GenerateNonNestedInitializationCode( + io::Printer* printer) { + int bytecode_estimate = 0; + if (descriptor_->extension_scope() == NULL) { + // Only applies to non-nested extensions. + printer->Print( + "$name$.internalInit(descriptor.getExtensions().get($index$));\n", + "name", UnderscoresToCamelCaseCheckReserved(descriptor_), "index", + StrCat(descriptor_->index())); + bytecode_estimate += 21; + } + return bytecode_estimate; +} + +int ImmutableExtensionGenerator::GenerateRegistrationCode( + io::Printer* printer) { + printer->Print("registry.add($scope$.$name$);\n", "scope", scope_, "name", + UnderscoresToCamelCaseCheckReserved(descriptor_)); + return 7; +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_extension.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_extension.h new file mode 100644 index 00000000..823190d7 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_extension.h @@ -0,0 +1,115 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_EXTENSION_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_EXTENSION_H__ + +#include <map> +#include <string> + +#include <stubs/common.h> + +namespace google { +namespace protobuf { +class FieldDescriptor; // descriptor.h +namespace compiler { +namespace java { +class Context; // context.h +class ClassNameResolver; // name_resolver.h +} // namespace java +} // namespace compiler +namespace io { +class Printer; // printer.h +} +} // namespace protobuf +} // namespace google + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +// Generates code for an extension, which may be within the scope of some +// message or may be at file scope. This is much simpler than FieldGenerator +// since extensions are just simple identifiers with interesting types. +class ExtensionGenerator { + public: + explicit ExtensionGenerator() {} + virtual ~ExtensionGenerator() {} + + virtual void Generate(io::Printer* printer) = 0; + + // Returns an estimate of the number of bytes the printed code will compile + // to + virtual int GenerateNonNestedInitializationCode(io::Printer* printer) = 0; + + // Returns an estimate of the number of bytes the printed code will compile + // to + virtual int GenerateRegistrationCode(io::Printer* printer) = 0; + + protected: + static void InitTemplateVars( + const FieldDescriptor* descriptor, const std::string& scope, + bool immutable, ClassNameResolver* name_resolver, + std::map<std::string, std::string>* vars_pointer); + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator); +}; + +class ImmutableExtensionGenerator : public ExtensionGenerator { + public: + explicit ImmutableExtensionGenerator(const FieldDescriptor* descriptor, + Context* context); + virtual ~ImmutableExtensionGenerator(); + + void Generate(io::Printer* printer) override; + int GenerateNonNestedInitializationCode(io::Printer* printer) override; + int GenerateRegistrationCode(io::Printer* printer) override; + + protected: + const FieldDescriptor* descriptor_; + ClassNameResolver* name_resolver_; + std::string scope_; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableExtensionGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_EXTENSION_H__ diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_extension_lite.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_extension_lite.cc new file mode 100644 index 00000000..cf1975a0 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_extension_lite.cc @@ -0,0 +1,115 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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. + +#include <compiler/java/java_extension_lite.h> + +#include <compiler/java/java_context.h> +#include <compiler/java/java_doc_comment.h> +#include <compiler/java/java_helpers.h> +#include <compiler/java/java_name_resolver.h> +#include <io/printer.h> +#include <stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +ImmutableExtensionLiteGenerator::ImmutableExtensionLiteGenerator( + const FieldDescriptor* descriptor, Context* context) + : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) { + if (descriptor_->extension_scope() != NULL) { + scope_ = + name_resolver_->GetImmutableClassName(descriptor_->extension_scope()); + } else { + scope_ = name_resolver_->GetImmutableClassName(descriptor_->file()); + } +} + +ImmutableExtensionLiteGenerator::~ImmutableExtensionLiteGenerator() {} + +void ImmutableExtensionLiteGenerator::Generate(io::Printer* printer) { + std::map<std::string, std::string> vars; + const bool kUseImmutableNames = true; + InitTemplateVars(descriptor_, scope_, kUseImmutableNames, name_resolver_, + &vars); + printer->Print(vars, "public static final int $constant_name$ = $number$;\n"); + + WriteFieldDocComment(printer, descriptor_); + if (descriptor_->is_repeated()) { + printer->Print( + vars, + "public static final\n" + " com.google.protobuf.GeneratedMessageLite.GeneratedExtension<\n" + " $containing_type$,\n" + " $type$> $name$ = com.google.protobuf.GeneratedMessageLite\n" + " .newRepeatedGeneratedExtension(\n" + " $containing_type$.getDefaultInstance(),\n" + " $prototype$,\n" + " $enum_map$,\n" + " $number$,\n" + " com.google.protobuf.WireFormat.FieldType.$type_constant$,\n" + " $packed$,\n" + " $singular_type$.class);\n"); + } else { + printer->Print( + vars, + "public static final\n" + " com.google.protobuf.GeneratedMessageLite.GeneratedExtension<\n" + " $containing_type$,\n" + " $type$> $name$ = com.google.protobuf.GeneratedMessageLite\n" + " .newSingularGeneratedExtension(\n" + " $containing_type$.getDefaultInstance(),\n" + " $default$,\n" + " $prototype$,\n" + " $enum_map$,\n" + " $number$,\n" + " com.google.protobuf.WireFormat.FieldType.$type_constant$,\n" + " $singular_type$.class);\n"); + } + printer->Annotate("name", descriptor_); +} + +int ImmutableExtensionLiteGenerator::GenerateNonNestedInitializationCode( + io::Printer* printer) { + return 0; +} + +int ImmutableExtensionLiteGenerator::GenerateRegistrationCode( + io::Printer* printer) { + printer->Print("registry.add($scope$.$name$);\n", "scope", scope_, "name", + UnderscoresToCamelCaseCheckReserved(descriptor_)); + return 7; +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_extension_lite.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_extension_lite.h new file mode 100644 index 00000000..0e38079f --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_extension_lite.h @@ -0,0 +1,75 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_EXTENSION_LITE_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_EXTENSION_LITE_H__ + +#include <map> +#include <string> + +#include <stubs/common.h> +#include <compiler/java/java_extension.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +// Generates code for a lite extension, which may be within the scope of some +// message or may be at file scope. This is much simpler than FieldGenerator +// since extensions are just simple identifiers with interesting types. +class ImmutableExtensionLiteGenerator : public ExtensionGenerator { + public: + explicit ImmutableExtensionLiteGenerator(const FieldDescriptor* descriptor, + Context* context); + virtual ~ImmutableExtensionLiteGenerator(); + + void Generate(io::Printer* printer) override; + + // Returns an estimate of the number of bytes the printed code will compile to + int GenerateNonNestedInitializationCode(io::Printer* printer) override; + + // Returns an estimate of the number of bytes the printed code will compile to + int GenerateRegistrationCode(io::Printer* printer) override; + + private: + const FieldDescriptor* descriptor_; + ClassNameResolver* name_resolver_; + std::string scope_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableExtensionLiteGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_EXTENSION_LITE_H__ diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_field.cc new file mode 100644 index 00000000..5da51b22 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_field.cc @@ -0,0 +1,312 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <compiler/java/java_field.h> + +#include <memory> + +#include <stubs/logging.h> +#include <stubs/common.h> +#include <compiler/java/java_context.h> +#include <compiler/java/java_enum_field.h> +#include <compiler/java/java_enum_field_lite.h> +#include <compiler/java/java_helpers.h> +#include <compiler/java/java_map_field.h> +#include <compiler/java/java_map_field_lite.h> +#include <compiler/java/java_message_field.h> +#include <compiler/java/java_message_field_lite.h> +#include <compiler/java/java_primitive_field.h> +#include <compiler/java/java_primitive_field_lite.h> +#include <compiler/java/java_string_field.h> +#include <compiler/java/java_string_field_lite.h> +#include <io/printer.h> +#include <stubs/strutil.h> +#include <stubs/substitute.h> + + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +namespace { + +ImmutableFieldGenerator* MakeImmutableGenerator(const FieldDescriptor* field, + int messageBitIndex, + int builderBitIndex, + Context* context) { + if (field->is_repeated()) { + switch (GetJavaType(field)) { + case JAVATYPE_MESSAGE: + if (IsMapEntry(field->message_type())) { + return new ImmutableMapFieldGenerator(field, messageBitIndex, + builderBitIndex, context); + } else { + return new RepeatedImmutableMessageFieldGenerator( + field, messageBitIndex, builderBitIndex, context); + } + case JAVATYPE_ENUM: + return new RepeatedImmutableEnumFieldGenerator( + field, messageBitIndex, builderBitIndex, context); + case JAVATYPE_STRING: + return new RepeatedImmutableStringFieldGenerator( + field, messageBitIndex, builderBitIndex, context); + default: + return new RepeatedImmutablePrimitiveFieldGenerator( + field, messageBitIndex, builderBitIndex, context); + } + } else { + if (IsRealOneof(field)) { + switch (GetJavaType(field)) { + case JAVATYPE_MESSAGE: + return new ImmutableMessageOneofFieldGenerator( + field, messageBitIndex, builderBitIndex, context); + case JAVATYPE_ENUM: + return new ImmutableEnumOneofFieldGenerator(field, messageBitIndex, + builderBitIndex, context); + case JAVATYPE_STRING: + return new ImmutableStringOneofFieldGenerator( + field, messageBitIndex, builderBitIndex, context); + default: + return new ImmutablePrimitiveOneofFieldGenerator( + field, messageBitIndex, builderBitIndex, context); + } + } else { + switch (GetJavaType(field)) { + case JAVATYPE_MESSAGE: + return new ImmutableMessageFieldGenerator(field, messageBitIndex, + builderBitIndex, context); + case JAVATYPE_ENUM: + return new ImmutableEnumFieldGenerator(field, messageBitIndex, + builderBitIndex, context); + case JAVATYPE_STRING: + return new ImmutableStringFieldGenerator(field, messageBitIndex, + builderBitIndex, context); + default: + return new ImmutablePrimitiveFieldGenerator(field, messageBitIndex, + builderBitIndex, context); + } + } + } +} + +ImmutableFieldLiteGenerator* MakeImmutableLiteGenerator( + const FieldDescriptor* field, int messageBitIndex, Context* context) { + if (field->is_repeated()) { + switch (GetJavaType(field)) { + case JAVATYPE_MESSAGE: + if (IsMapEntry(field->message_type())) { + return new ImmutableMapFieldLiteGenerator(field, messageBitIndex, + context); + } else { + return new RepeatedImmutableMessageFieldLiteGenerator( + field, messageBitIndex, context); + } + case JAVATYPE_ENUM: + return new RepeatedImmutableEnumFieldLiteGenerator( + field, messageBitIndex, context); + case JAVATYPE_STRING: + return new RepeatedImmutableStringFieldLiteGenerator( + field, messageBitIndex, context); + default: + return new RepeatedImmutablePrimitiveFieldLiteGenerator( + field, messageBitIndex, context); + } + } else { + if (IsRealOneof(field)) { + switch (GetJavaType(field)) { + case JAVATYPE_MESSAGE: + return new ImmutableMessageOneofFieldLiteGenerator( + field, messageBitIndex, context); + case JAVATYPE_ENUM: + return new ImmutableEnumOneofFieldLiteGenerator( + field, messageBitIndex, context); + case JAVATYPE_STRING: + return new ImmutableStringOneofFieldLiteGenerator( + field, messageBitIndex, context); + default: + return new ImmutablePrimitiveOneofFieldLiteGenerator( + field, messageBitIndex, context); + } + } else { + switch (GetJavaType(field)) { + case JAVATYPE_MESSAGE: + return new ImmutableMessageFieldLiteGenerator(field, messageBitIndex, + context); + case JAVATYPE_ENUM: + return new ImmutableEnumFieldLiteGenerator(field, messageBitIndex, + context); + case JAVATYPE_STRING: + return new ImmutableStringFieldLiteGenerator(field, messageBitIndex, + context); + default: + return new ImmutablePrimitiveFieldLiteGenerator( + field, messageBitIndex, context); + } + } + } +} + + +static inline void ReportUnexpectedPackedFieldsCall(io::Printer* printer) { + // Reaching here indicates a bug. Cases are: + // - This FieldGenerator should support packing, + // but this method should be overridden. + // - This FieldGenerator doesn't support packing, and this method + // should never have been called. + GOOGLE_LOG(FATAL) << "GenerateParsingCodeFromPacked() " + << "called on field generator that does not support packing."; +} + +} // namespace + +ImmutableFieldGenerator::~ImmutableFieldGenerator() {} + +void ImmutableFieldGenerator::GenerateParsingCodeFromPacked( + io::Printer* printer) const { + ReportUnexpectedPackedFieldsCall(printer); +} + +ImmutableFieldLiteGenerator::~ImmutableFieldLiteGenerator() {} + +// =================================================================== + +template <> +FieldGeneratorMap<ImmutableFieldGenerator>::FieldGeneratorMap( + const Descriptor* descriptor, Context* context) + : descriptor_(descriptor), field_generators_(descriptor->field_count()) { + // Construct all the FieldGenerators and assign them bit indices for their + // bit fields. + int messageBitIndex = 0; + int builderBitIndex = 0; + for (int i = 0; i < descriptor->field_count(); i++) { + ImmutableFieldGenerator* generator = MakeImmutableGenerator( + descriptor->field(i), messageBitIndex, builderBitIndex, context); + field_generators_[i].reset(generator); + messageBitIndex += generator->GetNumBitsForMessage(); + builderBitIndex += generator->GetNumBitsForBuilder(); + } +} + +template <> +FieldGeneratorMap<ImmutableFieldGenerator>::~FieldGeneratorMap() {} + +template <> +FieldGeneratorMap<ImmutableFieldLiteGenerator>::FieldGeneratorMap( + const Descriptor* descriptor, Context* context) + : descriptor_(descriptor), field_generators_(descriptor->field_count()) { + // Construct all the FieldGenerators and assign them bit indices for their + // bit fields. + int messageBitIndex = 0; + for (int i = 0; i < descriptor->field_count(); i++) { + ImmutableFieldLiteGenerator* generator = MakeImmutableLiteGenerator( + descriptor->field(i), messageBitIndex, context); + field_generators_[i].reset(generator); + messageBitIndex += generator->GetNumBitsForMessage(); + } +} + +template <> +FieldGeneratorMap<ImmutableFieldLiteGenerator>::~FieldGeneratorMap() {} + + +void SetCommonFieldVariables(const FieldDescriptor* descriptor, + const FieldGeneratorInfo* info, + std::map<std::string, std::string>* variables) { + (*variables)["field_name"] = descriptor->name(); + (*variables)["name"] = info->name; + (*variables)["classname"] = descriptor->containing_type()->name(); + (*variables)["capitalized_name"] = info->capitalized_name; + (*variables)["disambiguated_reason"] = info->disambiguated_reason; + (*variables)["constant_name"] = FieldConstantName(descriptor); + (*variables)["number"] = StrCat(descriptor->number()); + (*variables)["kt_dsl_builder"] = "_builder"; + // These variables are placeholders to pick out the beginning and ends of + // identifiers for annotations (when doing so with existing variables would + // be ambiguous or impossible). They should never be set to anything but the + // empty string. + (*variables)["{"] = ""; + (*variables)["}"] = ""; + (*variables)["kt_name"] = + IsForbiddenKotlin(info->name) ? info->name + "_" : info->name; + (*variables)["kt_capitalized_name"] = IsForbiddenKotlin(info->name) + ? info->capitalized_name + "_" + : info->capitalized_name; + if (!descriptor->is_repeated()) { + (*variables)["annotation_field_type"] = FieldTypeName(descriptor->type()); + } else if (GetJavaType(descriptor) == JAVATYPE_MESSAGE && + IsMapEntry(descriptor->message_type())) { + (*variables)["annotation_field_type"] = + std::string(FieldTypeName(descriptor->type())) + "MAP"; + } else { + (*variables)["annotation_field_type"] = + std::string(FieldTypeName(descriptor->type())) + "_LIST"; + if (descriptor->is_packed()) { + (*variables)["annotation_field_type"] = + (*variables)["annotation_field_type"] + "_PACKED"; + } + } +} + +void SetCommonOneofVariables(const FieldDescriptor* descriptor, + const OneofGeneratorInfo* info, + std::map<std::string, std::string>* variables) { + (*variables)["oneof_name"] = info->name; + (*variables)["oneof_capitalized_name"] = info->capitalized_name; + (*variables)["oneof_index"] = + StrCat(descriptor->containing_oneof()->index()); + (*variables)["oneof_stored_type"] = GetOneofStoredType(descriptor); + (*variables)["set_oneof_case_message"] = + info->name + "Case_ = " + StrCat(descriptor->number()); + (*variables)["clear_oneof_case_message"] = info->name + "Case_ = 0"; + (*variables)["has_oneof_case_message"] = + info->name + "Case_ == " + StrCat(descriptor->number()); +} + +void PrintExtraFieldInfo(const std::map<std::string, std::string>& variables, + io::Printer* printer) { + const std::map<std::string, std::string>::const_iterator it = + variables.find("disambiguated_reason"); + if (it != variables.end() && !it->second.empty()) { + printer->Print( + variables, + "// An alternative name is used for field \"$field_name$\" because:\n" + "// $disambiguated_reason$\n"); + } +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_field.h new file mode 100644 index 00000000..d010faac --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_field.h @@ -0,0 +1,191 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_FIELD_H__ + +#include <cstdint> +#include <map> +#include <memory> +#include <string> + +#include <stubs/logging.h> +#include <stubs/common.h> +#include <descriptor.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { +class Context; // context.h +class ClassNameResolver; // name_resolver.h +} // namespace java +} // namespace compiler +namespace io { +class Printer; // printer.h +} +} // namespace protobuf +} // namespace google + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +class ImmutableFieldGenerator { + public: + ImmutableFieldGenerator() {} + virtual ~ImmutableFieldGenerator(); + + virtual int GetNumBitsForMessage() const = 0; + virtual int GetNumBitsForBuilder() const = 0; + virtual void GenerateInterfaceMembers(io::Printer* printer) const = 0; + virtual void GenerateMembers(io::Printer* printer) const = 0; + virtual void GenerateBuilderMembers(io::Printer* printer) const = 0; + virtual void GenerateInitializationCode(io::Printer* printer) const = 0; + virtual void GenerateBuilderClearCode(io::Printer* printer) const = 0; + virtual void GenerateMergingCode(io::Printer* printer) const = 0; + virtual void GenerateBuildingCode(io::Printer* printer) const = 0; + virtual void GenerateParsingCode(io::Printer* printer) const = 0; + virtual void GenerateParsingCodeFromPacked(io::Printer* printer) const; + virtual void GenerateParsingDoneCode(io::Printer* printer) const = 0; + virtual void GenerateSerializationCode(io::Printer* printer) const = 0; + virtual void GenerateSerializedSizeCode(io::Printer* printer) const = 0; + virtual void GenerateFieldBuilderInitializationCode( + io::Printer* printer) const = 0; + virtual void GenerateKotlinDslMembers(io::Printer* printer) const = 0; + + virtual void GenerateEqualsCode(io::Printer* printer) const = 0; + virtual void GenerateHashCode(io::Printer* printer) const = 0; + + virtual std::string GetBoxedType() const = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableFieldGenerator); +}; + +class ImmutableFieldLiteGenerator { + public: + ImmutableFieldLiteGenerator() {} + virtual ~ImmutableFieldLiteGenerator(); + + virtual int GetNumBitsForMessage() const = 0; + virtual void GenerateInterfaceMembers(io::Printer* printer) const = 0; + virtual void GenerateMembers(io::Printer* printer) const = 0; + virtual void GenerateBuilderMembers(io::Printer* printer) const = 0; + virtual void GenerateInitializationCode(io::Printer* printer) const = 0; + virtual void GenerateFieldInfo(io::Printer* printer, + std::vector<uint16_t>* output) const = 0; + virtual void GenerateKotlinDslMembers(io::Printer* printer) const = 0; + + virtual std::string GetBoxedType() const = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableFieldLiteGenerator); +}; + + +// Convenience class which constructs FieldGenerators for a Descriptor. +template <typename FieldGeneratorType> +class FieldGeneratorMap { + public: + explicit FieldGeneratorMap(const Descriptor* descriptor, Context* context); + ~FieldGeneratorMap(); + + const FieldGeneratorType& get(const FieldDescriptor* field) const; + + private: + const Descriptor* descriptor_; + std::vector<std::unique_ptr<FieldGeneratorType>> field_generators_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorMap); +}; + +template <typename FieldGeneratorType> +inline const FieldGeneratorType& FieldGeneratorMap<FieldGeneratorType>::get( + const FieldDescriptor* field) const { + GOOGLE_CHECK_EQ(field->containing_type(), descriptor_); + return *field_generators_[field->index()]; +} + +// Instantiate template for mutable and immutable maps. +template <> +FieldGeneratorMap<ImmutableFieldGenerator>::FieldGeneratorMap( + const Descriptor* descriptor, Context* context); + +template <> +FieldGeneratorMap<ImmutableFieldGenerator>::~FieldGeneratorMap(); + + +template <> +FieldGeneratorMap<ImmutableFieldLiteGenerator>::FieldGeneratorMap( + const Descriptor* descriptor, Context* context); + +template <> +FieldGeneratorMap<ImmutableFieldLiteGenerator>::~FieldGeneratorMap(); + + +// Field information used in FieldGeneartors. +struct FieldGeneratorInfo { + std::string name; + std::string capitalized_name; + std::string disambiguated_reason; +}; + +// Oneof information used in OneofFieldGenerators. +struct OneofGeneratorInfo { + std::string name; + std::string capitalized_name; +}; + +// Set some common variables used in variable FieldGenerators. +void SetCommonFieldVariables(const FieldDescriptor* descriptor, + const FieldGeneratorInfo* info, + std::map<std::string, std::string>* variables); + +// Set some common oneof variables used in OneofFieldGenerators. +void SetCommonOneofVariables(const FieldDescriptor* descriptor, + const OneofGeneratorInfo* info, + std::map<std::string, std::string>* variables); + +// Print useful comments before a field's accessors. +void PrintExtraFieldInfo(const std::map<std::string, std::string>& variables, + io::Printer* printer); + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_FIELD_H__ diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_file.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_file.cc new file mode 100644 index 00000000..71a49ed4 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_file.cc @@ -0,0 +1,734 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <compiler/java/java_file.h> + +#include <memory> +#include <set> + +#include <compiler/java/java_context.h> +#include <compiler/java/java_enum.h> +#include <compiler/java/java_enum_lite.h> +#include <compiler/java/java_extension.h> +#include <compiler/java/java_generator_factory.h> +#include <compiler/java/java_helpers.h> +#include <compiler/java/java_message.h> +#include <compiler/java/java_name_resolver.h> +#include <compiler/java/java_service.h> +#include <compiler/java/java_shared_code_generator.h> +#include <compiler/code_generator.h> +#include <descriptor.pb.h> +#include <io/printer.h> +#include <io/zero_copy_stream.h> +#include <dynamic_message.h> +#include <stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +namespace { + +struct FieldDescriptorCompare { + bool operator()(const FieldDescriptor* f1, const FieldDescriptor* f2) const { + if (f1 == NULL) { + return false; + } + if (f2 == NULL) { + return true; + } + return f1->full_name() < f2->full_name(); + } +}; + +typedef std::set<const FieldDescriptor*, FieldDescriptorCompare> + FieldDescriptorSet; + +// Recursively searches the given message to collect extensions. +// Returns true if all the extensions can be recognized. The extensions will be +// appended in to the extensions parameter. +// Returns false when there are unknown fields, in which case the data in the +// extensions output parameter is not reliable and should be discarded. +bool CollectExtensions(const Message& message, FieldDescriptorSet* extensions) { + const Reflection* reflection = message.GetReflection(); + + // There are unknown fields that could be extensions, thus this call fails. + if (reflection->GetUnknownFields(message).field_count() > 0) return false; + + std::vector<const FieldDescriptor*> fields; + reflection->ListFields(message, &fields); + + for (int i = 0; i < fields.size(); i++) { + if (fields[i]->is_extension()) { + extensions->insert(fields[i]); + } + + if (GetJavaType(fields[i]) == JAVATYPE_MESSAGE) { + if (fields[i]->is_repeated()) { + int size = reflection->FieldSize(message, fields[i]); + for (int j = 0; j < size; j++) { + const Message& sub_message = + reflection->GetRepeatedMessage(message, fields[i], j); + if (!CollectExtensions(sub_message, extensions)) return false; + } + } else { + const Message& sub_message = reflection->GetMessage(message, fields[i]); + if (!CollectExtensions(sub_message, extensions)) return false; + } + } + } + + return true; +} + +// Finds all extensions in the given message and its sub-messages. If the +// message contains unknown fields (which could be extensions), then those +// extensions are defined in alternate_pool. +// The message will be converted to a DynamicMessage backed by alternate_pool +// in order to handle this case. +void CollectExtensions(const FileDescriptorProto& file_proto, + const DescriptorPool& alternate_pool, + FieldDescriptorSet* extensions, + const std::string& file_data) { + if (!CollectExtensions(file_proto, extensions)) { + // There are unknown fields in the file_proto, which are probably + // extensions. We need to parse the data into a dynamic message based on the + // builder-pool to find out all extensions. + const Descriptor* file_proto_desc = alternate_pool.FindMessageTypeByName( + file_proto.GetDescriptor()->full_name()); + GOOGLE_CHECK(file_proto_desc) + << "Find unknown fields in FileDescriptorProto when building " + << file_proto.name() + << ". It's likely that those fields are custom options, however, " + "descriptor.proto is not in the transitive dependencies. " + "This normally should not happen. Please report a bug."; + DynamicMessageFactory factory; + std::unique_ptr<Message> dynamic_file_proto( + factory.GetPrototype(file_proto_desc)->New()); + GOOGLE_CHECK(dynamic_file_proto.get() != NULL); + GOOGLE_CHECK(dynamic_file_proto->ParseFromString(file_data)); + + // Collect the extensions again from the dynamic message. There should be no + // more unknown fields this time, i.e. all the custom options should be + // parsed as extensions now. + extensions->clear(); + GOOGLE_CHECK(CollectExtensions(*dynamic_file_proto, extensions)) + << "Find unknown fields in FileDescriptorProto when building " + << file_proto.name() + << ". It's likely that those fields are custom options, however, " + "those options cannot be recognized in the builder pool. " + "This normally should not happen. Please report a bug."; + } +} + +// Our static initialization methods can become very, very large. +// So large that if we aren't careful we end up blowing the JVM's +// 64K bytes of bytecode/method. Fortunately, since these static +// methods are executed only once near the beginning of a program, +// there's usually plenty of stack space available and we can +// extend our methods by simply chaining them to another method +// with a tail call. This inserts the sequence call-next-method, +// end this one, begin-next-method as needed. +void MaybeRestartJavaMethod(io::Printer* printer, int* bytecode_estimate, + int* method_num, const char* chain_statement, + const char* method_decl) { + // The goal here is to stay under 64K bytes of jvm bytecode/method, + // since otherwise we hit a hardcoded limit in the jvm and javac will + // then fail with the error "code too large". This limit lets our + // estimates be off by a factor of two and still we're okay. + static const int bytesPerMethod = kMaxStaticSize; + + if ((*bytecode_estimate) > bytesPerMethod) { + ++(*method_num); + printer->Print(chain_statement, "method_num", StrCat(*method_num)); + printer->Outdent(); + printer->Print("}\n"); + printer->Print(method_decl, "method_num", StrCat(*method_num)); + printer->Indent(); + *bytecode_estimate = 0; + } +} +} // namespace + +FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options, + bool immutable_api) + : file_(file), + java_package_(FileJavaPackage(file, immutable_api)), + message_generators_(file->message_type_count()), + extension_generators_(file->extension_count()), + context_(new Context(file, options)), + name_resolver_(context_->GetNameResolver()), + options_(options), + immutable_api_(immutable_api) { + classname_ = name_resolver_->GetFileClassName(file, immutable_api); + generator_factory_.reset(new ImmutableGeneratorFactory(context_.get())); + for (int i = 0; i < file_->message_type_count(); ++i) { + message_generators_[i].reset( + generator_factory_->NewMessageGenerator(file_->message_type(i))); + } + for (int i = 0; i < file_->extension_count(); ++i) { + extension_generators_[i].reset( + generator_factory_->NewExtensionGenerator(file_->extension(i))); + } +} + +FileGenerator::~FileGenerator() {} + +bool FileGenerator::Validate(std::string* error) { + // Check that no class name matches the file's class name. This is a common + // problem that leads to Java compile errors that can be hard to understand. + // It's especially bad when using the java_multiple_files, since we would + // end up overwriting the outer class with one of the inner ones. + if (name_resolver_->HasConflictingClassName(file_, classname_, + NameEquality::EXACT_EQUAL)) { + error->assign(file_->name()); + error->append( + ": Cannot generate Java output because the file's outer class name, " + "\""); + error->append(classname_); + error->append( + "\", matches the name of one of the types declared inside it. " + "Please either rename the type or use the java_outer_classname " + "option to specify a different outer class name for the .proto file."); + return false; + } + // Similar to the check above, but ignore the case this time. This is not a + // problem on Linux, but will lead to Java compile errors on Windows / Mac + // because filenames are case-insensitive on those platforms. + if (name_resolver_->HasConflictingClassName( + file_, classname_, NameEquality::EQUAL_IGNORE_CASE)) { + GOOGLE_LOG(WARNING) + << file_->name() << ": The file's outer class name, \"" << classname_ + << "\", matches the name of one of the types declared inside it when " + << "case is ignored. This can cause compilation issues on Windows / " + << "MacOS. Please either rename the type or use the " + << "java_outer_classname option to specify a different outer class " + << "name for the .proto file to be safe."; + } + + // Print a warning if optimize_for = LITE_RUNTIME is used. + if (file_->options().optimize_for() == FileOptions::LITE_RUNTIME && + !options_.enforce_lite) { + GOOGLE_LOG(WARNING) + << "The optimize_for = LITE_RUNTIME option is no longer supported by " + << "protobuf Java code generator and is ignored--protoc will always " + << "generate full runtime code for Java. To use Java Lite runtime, " + << "users should use the Java Lite plugin instead. See:\n" + << " " + "https://github.com/protocolbuffers/protobuf/blob/master/java/" + "lite.md"; + } + return true; +} + +void FileGenerator::Generate(io::Printer* printer) { + // We don't import anything because we refer to all classes by their + // fully-qualified names in the generated source. + printer->Print( + "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" + "// source: $filename$\n" + "\n", + "filename", file_->name()); + if (!java_package_.empty()) { + printer->Print( + "package $package$;\n" + "\n", + "package", java_package_); + } + PrintGeneratedAnnotation( + printer, '$', options_.annotate_code ? classname_ + ".java.pb.meta" : ""); + + printer->Print( + "$deprecation$public final class $classname$ {\n" + " private $ctor$() {}\n", + "deprecation", + file_->options().deprecated() ? "@java.lang.Deprecated " : "", + "classname", classname_, "ctor", classname_); + printer->Annotate("classname", file_->name()); + printer->Indent(); + + // ----------------------------------------------------------------- + + printer->Print( + "public static void registerAllExtensions(\n" + " com.google.protobuf.ExtensionRegistryLite registry) {\n"); + + printer->Indent(); + + for (int i = 0; i < file_->extension_count(); i++) { + extension_generators_[i]->GenerateRegistrationCode(printer); + } + + for (int i = 0; i < file_->message_type_count(); i++) { + message_generators_[i]->GenerateExtensionRegistrationCode(printer); + } + + printer->Outdent(); + printer->Print("}\n"); + if (HasDescriptorMethods(file_, context_->EnforceLite())) { + // Overload registerAllExtensions for the non-lite usage to + // redundantly maintain the original signature (this is + // redundant because ExtensionRegistryLite now invokes + // ExtensionRegistry in the non-lite usage). Intent is + // to remove this in the future. + printer->Print( + "\n" + "public static void registerAllExtensions(\n" + " com.google.protobuf.ExtensionRegistry registry) {\n" + " registerAllExtensions(\n" + " (com.google.protobuf.ExtensionRegistryLite) registry);\n" + "}\n"); + } + + // ----------------------------------------------------------------- + + if (!MultipleJavaFiles(file_, immutable_api_)) { + for (int i = 0; i < file_->enum_type_count(); i++) { + if (HasDescriptorMethods(file_, context_->EnforceLite())) { + EnumGenerator(file_->enum_type(i), immutable_api_, context_.get()) + .Generate(printer); + } else { + EnumLiteGenerator(file_->enum_type(i), immutable_api_, context_.get()) + .Generate(printer); + } + } + for (int i = 0; i < file_->message_type_count(); i++) { + message_generators_[i]->GenerateInterface(printer); + message_generators_[i]->Generate(printer); + } + if (HasGenericServices(file_, context_->EnforceLite())) { + for (int i = 0; i < file_->service_count(); i++) { + std::unique_ptr<ServiceGenerator> generator( + generator_factory_->NewServiceGenerator(file_->service(i))); + generator->Generate(printer); + } + } + } + + // Extensions must be generated in the outer class since they are values, + // not classes. + for (int i = 0; i < file_->extension_count(); i++) { + extension_generators_[i]->Generate(printer); + } + + // Static variables. We'd like them to be final if possible, but due to + // the JVM's 64k size limit on static blocks, we have to initialize some + // of them in methods; thus they cannot be final. + int static_block_bytecode_estimate = 0; + for (int i = 0; i < file_->message_type_count(); i++) { + message_generators_[i]->GenerateStaticVariables( + printer, &static_block_bytecode_estimate); + } + + printer->Print("\n"); + + if (HasDescriptorMethods(file_, context_->EnforceLite())) { + if (immutable_api_) { + GenerateDescriptorInitializationCodeForImmutable(printer); + } else { + GenerateDescriptorInitializationCodeForMutable(printer); + } + } else { + printer->Print("static {\n"); + printer->Indent(); + int bytecode_estimate = 0; + int method_num = 0; + + for (int i = 0; i < file_->message_type_count(); i++) { + bytecode_estimate += + message_generators_[i]->GenerateStaticVariableInitializers(printer); + MaybeRestartJavaMethod( + printer, &bytecode_estimate, &method_num, + "_clinit_autosplit_$method_num$();\n", + "private static void _clinit_autosplit_$method_num$() {\n"); + } + + printer->Outdent(); + printer->Print("}\n"); + } + + printer->Print( + "\n" + "// @@protoc_insertion_point(outer_class_scope)\n"); + + printer->Outdent(); + printer->Print("}\n"); +} + +void FileGenerator::GenerateDescriptorInitializationCodeForImmutable( + io::Printer* printer) { + printer->Print( + "public static com.google.protobuf.Descriptors.FileDescriptor\n" + " getDescriptor() {\n" + " return descriptor;\n" + "}\n" + "private static $final$ com.google.protobuf.Descriptors.FileDescriptor\n" + " descriptor;\n" + "static {\n", + // TODO(dweis): Mark this as final. + "final", ""); + printer->Indent(); + + SharedCodeGenerator shared_code_generator(file_, options_); + shared_code_generator.GenerateDescriptors(printer); + + int bytecode_estimate = 0; + int method_num = 0; + + for (int i = 0; i < file_->message_type_count(); i++) { + bytecode_estimate += + message_generators_[i]->GenerateStaticVariableInitializers(printer); + MaybeRestartJavaMethod( + printer, &bytecode_estimate, &method_num, + "_clinit_autosplit_dinit_$method_num$();\n", + "private static void _clinit_autosplit_dinit_$method_num$() {\n"); + } + for (int i = 0; i < file_->extension_count(); i++) { + bytecode_estimate += + extension_generators_[i]->GenerateNonNestedInitializationCode(printer); + MaybeRestartJavaMethod( + printer, &bytecode_estimate, &method_num, + "_clinit_autosplit_dinit_$method_num$();\n", + "private static void _clinit_autosplit_dinit_$method_num$() {\n"); + } + + // Proto compiler builds a DescriptorPool, which holds all the descriptors to + // generate, when processing the ".proto" files. We call this DescriptorPool + // the parsed pool (a.k.a. file_->pool()). + // + // Note that when users try to extend the (.*)DescriptorProto in their + // ".proto" files, it does not affect the pre-built FileDescriptorProto class + // in proto compiler. When we put the descriptor data in the file_proto, those + // extensions become unknown fields. + // + // Now we need to find out all the extension value to the (.*)DescriptorProto + // in the file_proto message, and prepare an ExtensionRegistry to return. + // + // To find those extensions, we need to parse the data into a dynamic message + // of the FileDescriptor based on the builder-pool, then we can use + // reflections to find all extension fields + FileDescriptorProto file_proto; + file_->CopyTo(&file_proto); + std::string file_data; + file_proto.SerializeToString(&file_data); + FieldDescriptorSet extensions; + CollectExtensions(file_proto, *file_->pool(), &extensions, file_data); + + if (extensions.size() > 0) { + // Must construct an ExtensionRegistry containing all existing extensions + // and use it to parse the descriptor data again to recognize extensions. + printer->Print( + "com.google.protobuf.ExtensionRegistry registry =\n" + " com.google.protobuf.ExtensionRegistry.newInstance();\n"); + FieldDescriptorSet::iterator it; + for (it = extensions.begin(); it != extensions.end(); it++) { + std::unique_ptr<ExtensionGenerator> generator( + generator_factory_->NewExtensionGenerator(*it)); + bytecode_estimate += generator->GenerateRegistrationCode(printer); + MaybeRestartJavaMethod( + printer, &bytecode_estimate, &method_num, + "_clinit_autosplit_dinit_$method_num$(registry);\n", + "private static void _clinit_autosplit_dinit_$method_num$(\n" + " com.google.protobuf.ExtensionRegistry registry) {\n"); + } + printer->Print( + "com.google.protobuf.Descriptors.FileDescriptor\n" + " .internalUpdateFileDescriptor(descriptor, registry);\n"); + } + + // Force descriptor initialization of all dependencies. + for (int i = 0; i < file_->dependency_count(); i++) { + if (ShouldIncludeDependency(file_->dependency(i), true)) { + std::string dependency = + name_resolver_->GetImmutableClassName(file_->dependency(i)); + printer->Print("$dependency$.getDescriptor();\n", "dependency", + dependency); + } + } + + printer->Outdent(); + printer->Print("}\n"); +} + +void FileGenerator::GenerateDescriptorInitializationCodeForMutable( + io::Printer* printer) { + printer->Print( + "public static com.google.protobuf.Descriptors.FileDescriptor\n" + " getDescriptor() {\n" + " return descriptor;\n" + "}\n" + "private static final com.google.protobuf.Descriptors.FileDescriptor\n" + " descriptor;\n" + "static {\n"); + printer->Indent(); + + printer->Print( + "descriptor = $immutable_package$.$descriptor_classname$.descriptor;\n", + "immutable_package", FileJavaPackage(file_, true), "descriptor_classname", + name_resolver_->GetDescriptorClassName(file_)); + + for (int i = 0; i < file_->message_type_count(); i++) { + message_generators_[i]->GenerateStaticVariableInitializers(printer); + } + for (int i = 0; i < file_->extension_count(); i++) { + extension_generators_[i]->GenerateNonNestedInitializationCode(printer); + } + + // Check if custom options exist. If any, try to load immutable classes since + // custom options are only represented with immutable messages. + FileDescriptorProto file_proto; + file_->CopyTo(&file_proto); + std::string file_data; + file_proto.SerializeToString(&file_data); + FieldDescriptorSet extensions; + CollectExtensions(file_proto, *file_->pool(), &extensions, file_data); + + if (extensions.size() > 0) { + // Try to load immutable messages' outer class. Its initialization code + // will take care of interpreting custom options. + printer->Print( + "try {\n" + // Note that we have to load the immutable class dynamically here as + // we want the mutable code to be independent from the immutable code + // at compile time. It is required to implement dual-compile for + // mutable and immutable API in blaze. + " java.lang.Class<?> immutableClass = java.lang.Class.forName(\n" + " \"$immutable_classname$\");\n" + "} catch (java.lang.ClassNotFoundException e) {\n", + "immutable_classname", name_resolver_->GetImmutableClassName(file_)); + printer->Indent(); + + // The immutable class can not be found. We try our best to collect all + // custom option extensions to interpret the custom options. + printer->Print( + "com.google.protobuf.ExtensionRegistry registry =\n" + " com.google.protobuf.ExtensionRegistry.newInstance();\n" + "com.google.protobuf.MessageLite defaultExtensionInstance = null;\n"); + FieldDescriptorSet::iterator it; + for (it = extensions.begin(); it != extensions.end(); it++) { + const FieldDescriptor* field = *it; + std::string scope; + if (field->extension_scope() != NULL) { + scope = name_resolver_->GetMutableClassName(field->extension_scope()) + + ".getDescriptor()"; + } else { + scope = FileJavaPackage(field->file(), true) + "." + + name_resolver_->GetDescriptorClassName(field->file()) + + ".descriptor"; + } + if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + printer->Print( + "defaultExtensionInstance = com.google.protobuf.Internal\n" + " .getDefaultInstance(\"$class$\");\n" + "if (defaultExtensionInstance != null) {\n" + " registry.add(\n" + " $scope$.getExtensions().get($index$),\n" + " (com.google.protobuf.Message) defaultExtensionInstance);\n" + "}\n", + "scope", scope, "index", StrCat(field->index()), "class", + name_resolver_->GetImmutableClassName(field->message_type())); + } else { + printer->Print("registry.add($scope$.getExtensions().get($index$));\n", + "scope", scope, "index", StrCat(field->index())); + } + } + printer->Print( + "com.google.protobuf.Descriptors.FileDescriptor\n" + " .internalUpdateFileDescriptor(descriptor, registry);\n"); + + printer->Outdent(); + printer->Print("}\n"); + } + + // Force descriptor initialization of all dependencies. + for (int i = 0; i < file_->dependency_count(); i++) { + if (ShouldIncludeDependency(file_->dependency(i), false)) { + std::string dependency = + name_resolver_->GetMutableClassName(file_->dependency(i)); + printer->Print("$dependency$.getDescriptor();\n", "dependency", + dependency); + } + } + + printer->Outdent(); + printer->Print("}\n"); +} + +template <typename GeneratorClass, typename DescriptorClass> +static void GenerateSibling( + const std::string& package_dir, const std::string& java_package, + const DescriptorClass* descriptor, GeneratorContext* context, + std::vector<std::string>* file_list, bool annotate_code, + std::vector<std::string>* annotation_list, const std::string& name_suffix, + GeneratorClass* generator, + void (GeneratorClass::*pfn)(io::Printer* printer)) { + std::string filename = + package_dir + descriptor->name() + name_suffix + ".java"; + file_list->push_back(filename); + std::string info_full_path = filename + ".pb.meta"; + GeneratedCodeInfo annotations; + io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector( + &annotations); + + std::unique_ptr<io::ZeroCopyOutputStream> output(context->Open(filename)); + io::Printer printer(output.get(), '$', + annotate_code ? &annotation_collector : NULL); + + printer.Print( + "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" + "// source: $filename$\n" + "\n", + "filename", descriptor->file()->name()); + if (!java_package.empty()) { + printer.Print( + "package $package$;\n" + "\n", + "package", java_package); + } + + (generator->*pfn)(&printer); + + if (annotate_code) { + std::unique_ptr<io::ZeroCopyOutputStream> info_output( + context->Open(info_full_path)); + annotations.SerializeToZeroCopyStream(info_output.get()); + annotation_list->push_back(info_full_path); + } +} + +void FileGenerator::GenerateSiblings( + const std::string& package_dir, GeneratorContext* context, + std::vector<std::string>* file_list, + std::vector<std::string>* annotation_list) { + if (MultipleJavaFiles(file_, immutable_api_)) { + for (int i = 0; i < file_->enum_type_count(); i++) { + if (HasDescriptorMethods(file_, context_->EnforceLite())) { + EnumGenerator generator(file_->enum_type(i), immutable_api_, + context_.get()); + GenerateSibling<EnumGenerator>( + package_dir, java_package_, file_->enum_type(i), context, file_list, + options_.annotate_code, annotation_list, "", &generator, + &EnumGenerator::Generate); + } else { + EnumLiteGenerator generator(file_->enum_type(i), immutable_api_, + context_.get()); + GenerateSibling<EnumLiteGenerator>( + package_dir, java_package_, file_->enum_type(i), context, file_list, + options_.annotate_code, annotation_list, "", &generator, + &EnumLiteGenerator::Generate); + } + } + for (int i = 0; i < file_->message_type_count(); i++) { + if (immutable_api_) { + GenerateSibling<MessageGenerator>( + package_dir, java_package_, file_->message_type(i), context, + file_list, options_.annotate_code, annotation_list, "OrBuilder", + message_generators_[i].get(), &MessageGenerator::GenerateInterface); + } + GenerateSibling<MessageGenerator>( + package_dir, java_package_, file_->message_type(i), context, + file_list, options_.annotate_code, annotation_list, "", + message_generators_[i].get(), &MessageGenerator::Generate); + } + if (HasGenericServices(file_, context_->EnforceLite())) { + for (int i = 0; i < file_->service_count(); i++) { + std::unique_ptr<ServiceGenerator> generator( + generator_factory_->NewServiceGenerator(file_->service(i))); + GenerateSibling<ServiceGenerator>( + package_dir, java_package_, file_->service(i), context, file_list, + options_.annotate_code, annotation_list, "", generator.get(), + &ServiceGenerator::Generate); + } + } + } +} + +std::string FileGenerator::GetKotlinClassname() { + return name_resolver_->GetFileClassName(file_, immutable_api_, true); +} + +void FileGenerator::GenerateKotlinSiblings( + const std::string& package_dir, GeneratorContext* context, + std::vector<std::string>* file_list, + std::vector<std::string>* annotation_list) { + for (int i = 0; i < file_->message_type_count(); i++) { + const Descriptor* descriptor = file_->message_type(i); + MessageGenerator* generator = message_generators_[i].get(); + auto open_file = [context](const std::string& filename) { + return std::unique_ptr<io::ZeroCopyOutputStream>(context->Open(filename)); + }; + std::string filename = package_dir + descriptor->name() + "Kt.kt"; + file_list->push_back(filename); + std::string info_full_path = filename + ".pb.meta"; + GeneratedCodeInfo annotations; + io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector( + &annotations); + auto output = open_file(filename); + io::Printer printer( + output.get(), '$', + options_.annotate_code ? &annotation_collector : nullptr); + + printer.Print( + "//Generated by the protocol buffer compiler. DO NOT EDIT!\n" + "// source: $filename$\n" + "\n", + "filename", descriptor->file()->name()); + if (!java_package_.empty()) { + printer.Print( + "package $package$;\n" + "\n", + "package", java_package_); + } + + generator->GenerateKotlinMembers(&printer); + generator->GenerateTopLevelKotlinMembers(&printer); + + if (options_.annotate_code) { + auto info_output = open_file(info_full_path); + annotations.SerializeToZeroCopyStream(info_output.get()); + annotation_list->push_back(info_full_path); + } + } +} + +bool FileGenerator::ShouldIncludeDependency(const FileDescriptor* descriptor, + bool immutable_api) { + return true; +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_file.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_file.h new file mode 100644 index 00000000..80fb6e5d --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_file.h @@ -0,0 +1,125 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_FILE_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_FILE_H__ + +#include <memory> +#include <string> +#include <vector> +#include <stubs/common.h> +#include <compiler/java/java_options.h> + +namespace google { +namespace protobuf { +class FileDescriptor; // descriptor.h +namespace io { +class Printer; // printer.h +} +namespace compiler { +class GeneratorContext; // code_generator.h +namespace java { +class Context; // context.h +class MessageGenerator; // message.h +class GeneratorFactory; // generator_factory.h +class ExtensionGenerator; // extension.h +class ClassNameResolver; // name_resolver.h +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +class FileGenerator { + public: + FileGenerator(const FileDescriptor* file, const Options& options, + bool immutable_api = true); + ~FileGenerator(); + + // Checks for problems that would otherwise lead to cryptic compile errors. + // Returns true if there are no problems, or writes an error description to + // the given string and returns false otherwise. + bool Validate(std::string* error); + + void Generate(io::Printer* printer); + + std::string GetKotlinClassname(); + void GenerateKotlinSiblings(const std::string& package_dir, + GeneratorContext* generator_context, + std::vector<std::string>* file_list, + std::vector<std::string>* annotation_list); + + // If we aren't putting everything into one file, this will write all the + // files other than the outer file (i.e. one for each message, enum, and + // service type). + void GenerateSiblings(const std::string& package_dir, + GeneratorContext* generator_context, + std::vector<std::string>* file_list, + std::vector<std::string>* annotation_list); + + const std::string& java_package() { return java_package_; } + const std::string& classname() { return classname_; } + + private: + void GenerateDescriptorInitializationCodeForImmutable(io::Printer* printer); + void GenerateDescriptorInitializationCodeForMutable(io::Printer* printer); + + bool ShouldIncludeDependency(const FileDescriptor* descriptor, + bool immutable_api_); + + const FileDescriptor* file_; + std::string java_package_; + std::string classname_; + + std::vector<std::unique_ptr<MessageGenerator>> message_generators_; + std::vector<std::unique_ptr<ExtensionGenerator>> extension_generators_; + std::unique_ptr<GeneratorFactory> generator_factory_; + std::unique_ptr<Context> context_; + ClassNameResolver* name_resolver_; + const Options options_; + bool immutable_api_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_FILE_H__ diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_generator.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_generator.cc new file mode 100644 index 00000000..611a4d9c --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_generator.cc @@ -0,0 +1,211 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <compiler/java/java_generator.h> + + +#include <memory> + +#include <compiler/java/java_file.h> +#include <compiler/java/java_generator_factory.h> +#include <compiler/java/java_helpers.h> +#include <compiler/java/java_name_resolver.h> +#include <compiler/java/java_options.h> +#include <compiler/java/java_shared_code_generator.h> +#include <descriptor.pb.h> +#include <io/printer.h> +#include <io/zero_copy_stream.h> + +#include <stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + + +JavaGenerator::JavaGenerator() {} +JavaGenerator::~JavaGenerator() {} + +uint64_t JavaGenerator::GetSupportedFeatures() const { + return CodeGenerator::Feature::FEATURE_PROTO3_OPTIONAL; +} + +bool JavaGenerator::Generate(const FileDescriptor* file, + const std::string& parameter, + GeneratorContext* context, + std::string* error) const { + // ----------------------------------------------------------------- + // parse generator options + + std::vector<std::pair<std::string, std::string> > options; + ParseGeneratorParameter(parameter, &options); + Options file_options; + + for (int i = 0; i < options.size(); i++) { + if (options[i].first == "output_list_file") { + file_options.output_list_file = options[i].second; + } else if (options[i].first == "immutable") { + file_options.generate_immutable_code = true; + } else if (options[i].first == "mutable") { + file_options.generate_mutable_code = true; + } else if (options[i].first == "shared") { + file_options.generate_shared_code = true; + } else if (options[i].first == "lite") { + // Note: Java Lite does not guarantee API/ABI stability. We may choose to + // break existing API in order to boost performance / reduce code size. + file_options.enforce_lite = true; + } else if (options[i].first == "annotate_code") { + file_options.annotate_code = true; + } else if (options[i].first == "annotation_list_file") { + file_options.annotation_list_file = options[i].second; + } else { + *error = "Unknown generator option: " + options[i].first; + return false; + } + } + + if (file_options.enforce_lite && file_options.generate_mutable_code) { + *error = "lite runtime generator option cannot be used with mutable API."; + return false; + } + + // By default we generate immutable code and shared code for immutable API. + if (!file_options.generate_immutable_code && + !file_options.generate_mutable_code && + !file_options.generate_shared_code) { + file_options.generate_immutable_code = true; + file_options.generate_shared_code = true; + } + + // ----------------------------------------------------------------- + + + std::vector<std::string> all_files; + std::vector<std::string> all_annotations; + + + std::vector<FileGenerator*> file_generators; + if (file_options.generate_immutable_code) { + file_generators.push_back(new FileGenerator(file, file_options, + /* immutable = */ true)); + } + if (file_options.generate_mutable_code) { + file_generators.push_back(new FileGenerator(file, file_options, + /* mutable = */ false)); + } + + for (int i = 0; i < file_generators.size(); ++i) { + if (!file_generators[i]->Validate(error)) { + for (int j = 0; j < file_generators.size(); ++j) { + delete file_generators[j]; + } + return false; + } + } + + for (int i = 0; i < file_generators.size(); ++i) { + FileGenerator* file_generator = file_generators[i]; + + std::string package_dir = JavaPackageToDir(file_generator->java_package()); + + std::string java_filename = package_dir; + java_filename += file_generator->classname(); + java_filename += ".java"; + all_files.push_back(java_filename); + std::string info_full_path = java_filename + ".pb.meta"; + if (file_options.annotate_code) { + all_annotations.push_back(info_full_path); + } + + // Generate main java file. + std::unique_ptr<io::ZeroCopyOutputStream> output( + context->Open(java_filename)); + GeneratedCodeInfo annotations; + io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector( + &annotations); + io::Printer printer( + output.get(), '$', + file_options.annotate_code ? &annotation_collector : NULL); + + file_generator->Generate(&printer); + + // Generate sibling files. + file_generator->GenerateSiblings(package_dir, context, &all_files, + &all_annotations); + + if (file_options.annotate_code) { + std::unique_ptr<io::ZeroCopyOutputStream> info_output( + context->Open(info_full_path)); + annotations.SerializeToZeroCopyStream(info_output.get()); + } + } + + + for (int i = 0; i < file_generators.size(); ++i) { + delete file_generators[i]; + } + file_generators.clear(); + + // Generate output list if requested. + if (!file_options.output_list_file.empty()) { + // Generate output list. This is just a simple text file placed in a + // deterministic location which lists the .java files being generated. + std::unique_ptr<io::ZeroCopyOutputStream> srclist_raw_output( + context->Open(file_options.output_list_file)); + io::Printer srclist_printer(srclist_raw_output.get(), '$'); + for (int i = 0; i < all_files.size(); i++) { + srclist_printer.Print("$filename$\n", "filename", all_files[i]); + } + } + + if (!file_options.annotation_list_file.empty()) { + // Generate output list. This is just a simple text file placed in a + // deterministic location which lists the .java files being generated. + std::unique_ptr<io::ZeroCopyOutputStream> annotation_list_raw_output( + context->Open(file_options.annotation_list_file)); + io::Printer annotation_list_printer(annotation_list_raw_output.get(), '$'); + for (int i = 0; i < all_annotations.size(); i++) { + annotation_list_printer.Print("$filename$\n", "filename", + all_annotations[i]); + } + } + + return true; +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_generator.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_generator.h new file mode 100644 index 00000000..7910cc03 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_generator.h @@ -0,0 +1,76 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Generates Java code for a given .proto file. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__ + +#include <string> +#include <compiler/code_generator.h> + +#include <port_def.inc> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +// CodeGenerator implementation which generates Java code. If you create your +// own protocol compiler binary and you want it to support Java output, you +// can do so by registering an instance of this CodeGenerator with the +// CommandLineInterface in your main() function. +class PROTOC_EXPORT JavaGenerator : public CodeGenerator { + public: + JavaGenerator(); + ~JavaGenerator(); + + // implements CodeGenerator ---------------------------------------- + bool Generate(const FileDescriptor* file, const std::string& parameter, + GeneratorContext* context, std::string* error) const override; + + uint64_t GetSupportedFeatures() const override; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(JavaGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +#include <port_undef.inc> + +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_H__ diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_generator_factory.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_generator_factory.cc new file mode 100644 index 00000000..50fa50b0 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_generator_factory.cc @@ -0,0 +1,86 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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: liujisi@google.com (Pherl Liu) + +#include <compiler/java/java_generator_factory.h> + +#include <compiler/java/java_context.h> +#include <compiler/java/java_enum_field.h> +#include <compiler/java/java_extension.h> +#include <compiler/java/java_extension_lite.h> +#include <compiler/java/java_field.h> +#include <compiler/java/java_helpers.h> +#include <compiler/java/java_message.h> +#include <compiler/java/java_message_lite.h> +#include <compiler/java/java_service.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +GeneratorFactory::GeneratorFactory() {} +GeneratorFactory::~GeneratorFactory() {} + +// =================================================================== + +ImmutableGeneratorFactory::ImmutableGeneratorFactory(Context* context) + : context_(context) {} +ImmutableGeneratorFactory::~ImmutableGeneratorFactory() {} + +MessageGenerator* ImmutableGeneratorFactory::NewMessageGenerator( + const Descriptor* descriptor) const { + if (HasDescriptorMethods(descriptor, context_->EnforceLite())) { + return new ImmutableMessageGenerator(descriptor, context_); + } else { + return new ImmutableMessageLiteGenerator(descriptor, context_); + } +} + +ExtensionGenerator* ImmutableGeneratorFactory::NewExtensionGenerator( + const FieldDescriptor* descriptor) const { + if (HasDescriptorMethods(descriptor->file(), context_->EnforceLite())) { + return new ImmutableExtensionGenerator(descriptor, context_); + } else { + return new ImmutableExtensionLiteGenerator(descriptor, context_); + } +} + +ServiceGenerator* ImmutableGeneratorFactory::NewServiceGenerator( + const ServiceDescriptor* descriptor) const { + return new ImmutableServiceGenerator(descriptor, context_); +} + + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_generator_factory.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_generator_factory.h new file mode 100644 index 00000000..a0a827a5 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_generator_factory.h @@ -0,0 +1,103 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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: liujisi@google.com (Pherl Liu) + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_FACTORY_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_FACTORY_H__ + +#include <stubs/common.h> + +namespace google { +namespace protobuf { +class FieldDescriptor; // descriptor.h +class Descriptor; // descriptor.h +class ServiceDescriptor; // descriptor.h +namespace compiler { +namespace java { +class MessageGenerator; // message.h +class ExtensionGenerator; // extension.h +class ServiceGenerator; // service.h +class Context; // context.h +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +class GeneratorFactory { + public: + GeneratorFactory(); + virtual ~GeneratorFactory(); + + virtual MessageGenerator* NewMessageGenerator( + const Descriptor* descriptor) const = 0; + + virtual ExtensionGenerator* NewExtensionGenerator( + const FieldDescriptor* descriptor) const = 0; + + virtual ServiceGenerator* NewServiceGenerator( + const ServiceDescriptor* descriptor) const = 0; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratorFactory); +}; + +// Factory that creates generators for immutable-default messages. +class ImmutableGeneratorFactory : public GeneratorFactory { + public: + ImmutableGeneratorFactory(Context* context); + virtual ~ImmutableGeneratorFactory(); + + MessageGenerator* NewMessageGenerator( + const Descriptor* descriptor) const override; + + ExtensionGenerator* NewExtensionGenerator( + const FieldDescriptor* descriptor) const override; + + ServiceGenerator* NewServiceGenerator( + const ServiceDescriptor* descriptor) const override; + + private: + Context* context_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableGeneratorFactory); +}; + + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_GENERATOR_FACTORY_H__ diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_helpers.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_helpers.cc new file mode 100644 index 00000000..0ce86ba9 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_helpers.cc @@ -0,0 +1,1100 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <compiler/java/java_helpers.h> + +#include <algorithm> +#include <cstdint> +#include <limits> +#include <unordered_set> +#include <vector> + +#include <stubs/stringprintf.h> +#include <compiler/java/java_name_resolver.h> +#include <compiler/java/java_names.h> +#include <descriptor.pb.h> +#include <wire_format.h> +#include <stubs/strutil.h> +#include <stubs/substitute.h> +#include <stubs/hash.h> // for hash<T *> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +using internal::WireFormat; +using internal::WireFormatLite; + +const char kThickSeparator[] = + "// ===================================================================\n"; +const char kThinSeparator[] = + "// -------------------------------------------------------------------\n"; + +namespace { + +const char* kDefaultPackage = ""; + +// Names that should be avoided as field names. +// Using them will cause the compiler to generate accessors whose names are +// colliding with methods defined in base classes. +const char* kForbiddenWordList[] = { + // message base class: + "cached_size", + "serialized_size", + // java.lang.Object: + "class", +}; + +const std::unordered_set<std::string>* kReservedNames = + new std::unordered_set<std::string>({ + "abstract", "assert", "boolean", "break", "byte", + "case", "catch", "char", "class", "const", + "continue", "default", "do", "double", "else", + "enum", "extends", "final", "finally", "float", + "for", "goto", "if", "implements", "import", + "instanceof", "int", "interface", "long", "native", + "new", "package", "private", "protected", "public", + "return", "short", "static", "strictfp", "super", + "switch", "synchronized", "this", "throw", "throws", + "transient", "try", "void", "volatile", "while", + }); + +bool IsForbidden(const std::string& field_name) { + for (int i = 0; i < GOOGLE_ARRAYSIZE(kForbiddenWordList); ++i) { + if (field_name == kForbiddenWordList[i]) { + return true; + } + } + return false; +} + +std::string FieldName(const FieldDescriptor* field) { + std::string field_name; + // Groups are hacky: The name of the field is just the lower-cased name + // of the group type. In Java, though, we would like to retain the original + // capitalization of the type name. + if (GetType(field) == FieldDescriptor::TYPE_GROUP) { + field_name = field->message_type()->name(); + } else { + field_name = field->name(); + } + if (IsForbidden(field_name)) { + // Append a trailing "#" to indicate that the name should be decorated to + // avoid collision with other names. + field_name += "#"; + } + return field_name; +} + + +} // namespace + +void PrintGeneratedAnnotation(io::Printer* printer, char delimiter, + const std::string& annotation_file) { + if (annotation_file.empty()) { + return; + } + std::string ptemplate = + "@javax.annotation.Generated(value=\"protoc\", comments=\"annotations:"; + ptemplate.push_back(delimiter); + ptemplate.append("annotation_file"); + ptemplate.push_back(delimiter); + ptemplate.append("\")\n"); + printer->Print(ptemplate.c_str(), "annotation_file", annotation_file); +} + +void PrintEnumVerifierLogic(io::Printer* printer, + const FieldDescriptor* descriptor, + const std::map<std::string, std::string>& variables, + const char* var_name, + const char* terminating_string, bool enforce_lite) { + std::string enum_verifier_string = + enforce_lite ? StrCat(var_name, ".internalGetVerifier()") + : StrCat( + "new com.google.protobuf.Internal.EnumVerifier() {\n" + " @java.lang.Override\n" + " public boolean isInRange(int number) {\n" + " return ", + var_name, + ".forNumber(number) != null;\n" + " }\n" + " }"); + printer->Print( + variables, + StrCat(enum_verifier_string, terminating_string).c_str()); +} + +std::string UnderscoresToCamelCase(const std::string& input, + bool cap_next_letter) { + GOOGLE_CHECK(!input.empty()); + std::string result; + // Note: I distrust ctype.h due to locales. + for (int i = 0; i < input.size(); i++) { + if ('a' <= input[i] && input[i] <= 'z') { + if (cap_next_letter) { + result += input[i] + ('A' - 'a'); + } else { + result += input[i]; + } + cap_next_letter = false; + } else if ('A' <= input[i] && input[i] <= 'Z') { + if (i == 0 && !cap_next_letter) { + // Force first letter to lower-case unless explicitly told to + // capitalize it. + result += input[i] + ('a' - 'A'); + } else { + // Capital letters after the first are left as-is. + result += input[i]; + } + cap_next_letter = false; + } else if ('0' <= input[i] && input[i] <= '9') { + result += input[i]; + cap_next_letter = true; + } else { + cap_next_letter = true; + } + } + // Add a trailing "_" if the name should be altered. + if (input[input.size() - 1] == '#') { + result += '_'; + } + return result; +} + +std::string ToCamelCase(const std::string& input, bool lower_first) { + bool capitalize_next = !lower_first; + std::string result; + result.reserve(input.size()); + + for (char i : input) { + if (i == '_') { + capitalize_next = true; + } else if (capitalize_next) { + result.push_back(ToUpperCh(i)); + capitalize_next = false; + } else { + result.push_back(i); + } + } + + // Lower-case the first letter. + if (lower_first && !result.empty()) { + result[0] = ToLowerCh(result[0]); + } + + return result; +} + +char ToUpperCh(char ch) { + return (ch >= 'a' && ch <= 'z') ? (ch - 'a' + 'A') : ch; +} + +char ToLowerCh(char ch) { + return (ch >= 'A' && ch <= 'Z') ? (ch - 'A' + 'a') : ch; +} + +std::string UnderscoresToCamelCase(const FieldDescriptor* field) { + return UnderscoresToCamelCase(FieldName(field), false); +} + +std::string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field) { + return UnderscoresToCamelCase(FieldName(field), true); +} + +std::string CapitalizedFieldName(const FieldDescriptor* field) { + return UnderscoresToCapitalizedCamelCase(field); +} + +std::string UnderscoresToCamelCase(const MethodDescriptor* method) { + return UnderscoresToCamelCase(method->name(), false); +} + +std::string UnderscoresToCamelCaseCheckReserved(const FieldDescriptor* field) { + std::string name = UnderscoresToCamelCase(field); + if (kReservedNames->find(name) != kReservedNames->end()) { + return name + "_"; + } + return name; +} + +bool IsForbiddenKotlin(const std::string& field_name) { + // Names that should be avoided as field names in Kotlin. + // All Kotlin hard keywords are in this list. + const std::unordered_set<std::string>* kKotlinForbiddenNames = + new std::unordered_set<std::string>({ + "as", "as?", "break", "class", "continue", "do", + "else", "false", "for", "fun", "if", "in", + "!in", "interface", "is", "!is", "null", "object", + "package", "return", "super", "this", "throw", "true", + "try", "typealias", "typeof", "val", "var", "when", + "while", + }); + return kKotlinForbiddenNames->find(field_name) != + kKotlinForbiddenNames->end(); +} + +std::string UniqueFileScopeIdentifier(const Descriptor* descriptor) { + return "static_" + StringReplace(descriptor->full_name(), ".", "_", true); +} + +std::string CamelCaseFieldName(const FieldDescriptor* field) { + std::string fieldName = UnderscoresToCamelCase(field); + if ('0' <= fieldName[0] && fieldName[0] <= '9') { + return '_' + fieldName; + } + return fieldName; +} + +std::string FileClassName(const FileDescriptor* file, bool immutable) { + ClassNameResolver name_resolver; + return name_resolver.GetFileClassName(file, immutable); +} + +std::string FileJavaPackage(const FileDescriptor* file, bool immutable) { + std::string result; + + if (file->options().has_java_package()) { + result = file->options().java_package(); + } else { + result = kDefaultPackage; + if (!file->package().empty()) { + if (!result.empty()) result += '.'; + result += file->package(); + } + } + + return result; +} + +std::string FileJavaPackage(const FileDescriptor* file) { + return FileJavaPackage(file, true /* immutable */); +} + +std::string JavaPackageToDir(std::string package_name) { + std::string package_dir = StringReplace(package_name, ".", "/", true); + if (!package_dir.empty()) package_dir += "/"; + return package_dir; +} + +std::string ClassName(const Descriptor* descriptor) { + ClassNameResolver name_resolver; + return name_resolver.GetClassName(descriptor, true); +} + +std::string ClassName(const EnumDescriptor* descriptor) { + ClassNameResolver name_resolver; + return name_resolver.GetClassName(descriptor, true); +} + +std::string ClassName(const ServiceDescriptor* descriptor) { + ClassNameResolver name_resolver; + return name_resolver.GetClassName(descriptor, true); +} + +std::string ClassName(const FileDescriptor* descriptor) { + ClassNameResolver name_resolver; + return name_resolver.GetClassName(descriptor, true); +} + + +std::string ExtraMessageInterfaces(const Descriptor* descriptor) { + std::string interfaces = "// @@protoc_insertion_point(message_implements:" + + descriptor->full_name() + ")"; + return interfaces; +} + + +std::string ExtraBuilderInterfaces(const Descriptor* descriptor) { + std::string interfaces = "// @@protoc_insertion_point(builder_implements:" + + descriptor->full_name() + ")"; + return interfaces; +} + +std::string ExtraMessageOrBuilderInterfaces(const Descriptor* descriptor) { + std::string interfaces = "// @@protoc_insertion_point(interface_extends:" + + descriptor->full_name() + ")"; + return interfaces; +} + +std::string FieldConstantName(const FieldDescriptor* field) { + std::string name = field->name() + "_FIELD_NUMBER"; + ToUpper(&name); + return name; +} + +FieldDescriptor::Type GetType(const FieldDescriptor* field) { + return field->type(); +} + +JavaType GetJavaType(const FieldDescriptor* field) { + switch (GetType(field)) { + case FieldDescriptor::TYPE_INT32: + case FieldDescriptor::TYPE_UINT32: + case FieldDescriptor::TYPE_SINT32: + case FieldDescriptor::TYPE_FIXED32: + case FieldDescriptor::TYPE_SFIXED32: + return JAVATYPE_INT; + + case FieldDescriptor::TYPE_INT64: + case FieldDescriptor::TYPE_UINT64: + case FieldDescriptor::TYPE_SINT64: + case FieldDescriptor::TYPE_FIXED64: + case FieldDescriptor::TYPE_SFIXED64: + return JAVATYPE_LONG; + + case FieldDescriptor::TYPE_FLOAT: + return JAVATYPE_FLOAT; + + case FieldDescriptor::TYPE_DOUBLE: + return JAVATYPE_DOUBLE; + + case FieldDescriptor::TYPE_BOOL: + return JAVATYPE_BOOLEAN; + + case FieldDescriptor::TYPE_STRING: + return JAVATYPE_STRING; + + case FieldDescriptor::TYPE_BYTES: + return JAVATYPE_BYTES; + + case FieldDescriptor::TYPE_ENUM: + return JAVATYPE_ENUM; + + case FieldDescriptor::TYPE_GROUP: + case FieldDescriptor::TYPE_MESSAGE: + return JAVATYPE_MESSAGE; + + // No default because we want the compiler to complain if any new + // types are added. + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return JAVATYPE_INT; +} + +const char* PrimitiveTypeName(JavaType type) { + switch (type) { + case JAVATYPE_INT: + return "int"; + case JAVATYPE_LONG: + return "long"; + case JAVATYPE_FLOAT: + return "float"; + case JAVATYPE_DOUBLE: + return "double"; + case JAVATYPE_BOOLEAN: + return "boolean"; + case JAVATYPE_STRING: + return "java.lang.String"; + case JAVATYPE_BYTES: + return "com.google.protobuf.ByteString"; + case JAVATYPE_ENUM: + return NULL; + case JAVATYPE_MESSAGE: + return NULL; + + // No default because we want the compiler to complain if any new + // JavaTypes are added. + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return NULL; +} + +const char* PrimitiveTypeName(const FieldDescriptor* descriptor) { + return PrimitiveTypeName(GetJavaType(descriptor)); +} + +const char* BoxedPrimitiveTypeName(JavaType type) { + switch (type) { + case JAVATYPE_INT: + return "java.lang.Integer"; + case JAVATYPE_LONG: + return "java.lang.Long"; + case JAVATYPE_FLOAT: + return "java.lang.Float"; + case JAVATYPE_DOUBLE: + return "java.lang.Double"; + case JAVATYPE_BOOLEAN: + return "java.lang.Boolean"; + case JAVATYPE_STRING: + return "java.lang.String"; + case JAVATYPE_BYTES: + return "com.google.protobuf.ByteString"; + case JAVATYPE_ENUM: + return NULL; + case JAVATYPE_MESSAGE: + return NULL; + + // No default because we want the compiler to complain if any new + // JavaTypes are added. + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return NULL; +} + +const char* BoxedPrimitiveTypeName(const FieldDescriptor* descriptor) { + return BoxedPrimitiveTypeName(GetJavaType(descriptor)); +} + +const char* KotlinTypeName(JavaType type) { + switch (type) { + case JAVATYPE_INT: + return "kotlin.Int"; + case JAVATYPE_LONG: + return "kotlin.Long"; + case JAVATYPE_FLOAT: + return "kotlin.Float"; + case JAVATYPE_DOUBLE: + return "kotlin.Double"; + case JAVATYPE_BOOLEAN: + return "kotlin.Boolean"; + case JAVATYPE_STRING: + return "kotlin.String"; + case JAVATYPE_BYTES: + return "com.google.protobuf.ByteString"; + case JAVATYPE_ENUM: + return NULL; + case JAVATYPE_MESSAGE: + return NULL; + + // No default because we want the compiler to complain if any new + // JavaTypes are added. + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return NULL; +} + +std::string GetOneofStoredType(const FieldDescriptor* field) { + const JavaType javaType = GetJavaType(field); + switch (javaType) { + case JAVATYPE_ENUM: + return "java.lang.Integer"; + case JAVATYPE_MESSAGE: + return ClassName(field->message_type()); + default: + return BoxedPrimitiveTypeName(javaType); + } +} + +const char* FieldTypeName(FieldDescriptor::Type field_type) { + switch (field_type) { + case FieldDescriptor::TYPE_INT32: + return "INT32"; + case FieldDescriptor::TYPE_UINT32: + return "UINT32"; + case FieldDescriptor::TYPE_SINT32: + return "SINT32"; + case FieldDescriptor::TYPE_FIXED32: + return "FIXED32"; + case FieldDescriptor::TYPE_SFIXED32: + return "SFIXED32"; + case FieldDescriptor::TYPE_INT64: + return "INT64"; + case FieldDescriptor::TYPE_UINT64: + return "UINT64"; + case FieldDescriptor::TYPE_SINT64: + return "SINT64"; + case FieldDescriptor::TYPE_FIXED64: + return "FIXED64"; + case FieldDescriptor::TYPE_SFIXED64: + return "SFIXED64"; + case FieldDescriptor::TYPE_FLOAT: + return "FLOAT"; + case FieldDescriptor::TYPE_DOUBLE: + return "DOUBLE"; + case FieldDescriptor::TYPE_BOOL: + return "BOOL"; + case FieldDescriptor::TYPE_STRING: + return "STRING"; + case FieldDescriptor::TYPE_BYTES: + return "BYTES"; + case FieldDescriptor::TYPE_ENUM: + return "ENUM"; + case FieldDescriptor::TYPE_GROUP: + return "GROUP"; + case FieldDescriptor::TYPE_MESSAGE: + return "MESSAGE"; + + // No default because we want the compiler to complain if any new + // types are added. + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return NULL; +} + +bool AllAscii(const std::string& text) { + for (int i = 0; i < text.size(); i++) { + if ((text[i] & 0x80) != 0) { + return false; + } + } + return true; +} + +std::string DefaultValue(const FieldDescriptor* field, bool immutable, + ClassNameResolver* name_resolver) { + // Switch on CppType since we need to know which default_value_* method + // of FieldDescriptor to call. + switch (field->cpp_type()) { + case FieldDescriptor::CPPTYPE_INT32: + return StrCat(field->default_value_int32()); + case FieldDescriptor::CPPTYPE_UINT32: + // Need to print as a signed int since Java has no unsigned. + return StrCat(static_cast<int32_t>(field->default_value_uint32())); + case FieldDescriptor::CPPTYPE_INT64: + return StrCat(field->default_value_int64()) + "L"; + case FieldDescriptor::CPPTYPE_UINT64: + return StrCat(static_cast<int64_t>(field->default_value_uint64())) + + "L"; + case FieldDescriptor::CPPTYPE_DOUBLE: { + double value = field->default_value_double(); + if (value == std::numeric_limits<double>::infinity()) { + return "Double.POSITIVE_INFINITY"; + } else if (value == -std::numeric_limits<double>::infinity()) { + return "Double.NEGATIVE_INFINITY"; + } else if (value != value) { + return "Double.NaN"; + } else { + return SimpleDtoa(value) + "D"; + } + } + case FieldDescriptor::CPPTYPE_FLOAT: { + float value = field->default_value_float(); + if (value == std::numeric_limits<float>::infinity()) { + return "Float.POSITIVE_INFINITY"; + } else if (value == -std::numeric_limits<float>::infinity()) { + return "Float.NEGATIVE_INFINITY"; + } else if (value != value) { + return "Float.NaN"; + } else { + return SimpleFtoa(value) + "F"; + } + } + case FieldDescriptor::CPPTYPE_BOOL: + return field->default_value_bool() ? "true" : "false"; + case FieldDescriptor::CPPTYPE_STRING: + if (GetType(field) == FieldDescriptor::TYPE_BYTES) { + if (field->has_default_value()) { + // See comments in Internal.java for gory details. + return strings::Substitute( + "com.google.protobuf.Internal.bytesDefaultValue(\"$0\")", + CEscape(field->default_value_string())); + } else { + return "com.google.protobuf.ByteString.EMPTY"; + } + } else { + if (AllAscii(field->default_value_string())) { + // All chars are ASCII. In this case CEscape() works fine. + return "\"" + CEscape(field->default_value_string()) + "\""; + } else { + // See comments in Internal.java for gory details. + return strings::Substitute( + "com.google.protobuf.Internal.stringDefaultValue(\"$0\")", + CEscape(field->default_value_string())); + } + } + + case FieldDescriptor::CPPTYPE_ENUM: + return name_resolver->GetClassName(field->enum_type(), immutable) + "." + + field->default_value_enum()->name(); + + case FieldDescriptor::CPPTYPE_MESSAGE: + return name_resolver->GetClassName(field->message_type(), immutable) + + ".getDefaultInstance()"; + + // No default because we want the compiler to complain if any new + // types are added. + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return ""; +} + +bool IsDefaultValueJavaDefault(const FieldDescriptor* field) { + // Switch on CppType since we need to know which default_value_* method + // of FieldDescriptor to call. + switch (field->cpp_type()) { + case FieldDescriptor::CPPTYPE_INT32: + return field->default_value_int32() == 0; + case FieldDescriptor::CPPTYPE_UINT32: + return field->default_value_uint32() == 0; + case FieldDescriptor::CPPTYPE_INT64: + return field->default_value_int64() == 0L; + case FieldDescriptor::CPPTYPE_UINT64: + return field->default_value_uint64() == 0L; + case FieldDescriptor::CPPTYPE_DOUBLE: + return field->default_value_double() == 0.0; + case FieldDescriptor::CPPTYPE_FLOAT: + return field->default_value_float() == 0.0; + case FieldDescriptor::CPPTYPE_BOOL: + return field->default_value_bool() == false; + case FieldDescriptor::CPPTYPE_ENUM: + return field->default_value_enum()->number() == 0; + case FieldDescriptor::CPPTYPE_STRING: + case FieldDescriptor::CPPTYPE_MESSAGE: + return false; + + // No default because we want the compiler to complain if any new + // types are added. + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return false; +} + +bool IsByteStringWithCustomDefaultValue(const FieldDescriptor* field) { + return GetJavaType(field) == JAVATYPE_BYTES && + field->default_value_string() != ""; +} + +const char* bit_masks[] = { + "0x00000001", "0x00000002", "0x00000004", "0x00000008", + "0x00000010", "0x00000020", "0x00000040", "0x00000080", + + "0x00000100", "0x00000200", "0x00000400", "0x00000800", + "0x00001000", "0x00002000", "0x00004000", "0x00008000", + + "0x00010000", "0x00020000", "0x00040000", "0x00080000", + "0x00100000", "0x00200000", "0x00400000", "0x00800000", + + "0x01000000", "0x02000000", "0x04000000", "0x08000000", + "0x10000000", "0x20000000", "0x40000000", "0x80000000", +}; + +std::string GetBitFieldName(int index) { + std::string varName = "bitField"; + varName += StrCat(index); + varName += "_"; + return varName; +} + +std::string GetBitFieldNameForBit(int bitIndex) { + return GetBitFieldName(bitIndex / 32); +} + +namespace { + +std::string GenerateGetBitInternal(const std::string& prefix, int bitIndex) { + std::string varName = prefix + GetBitFieldNameForBit(bitIndex); + int bitInVarIndex = bitIndex % 32; + + std::string mask = bit_masks[bitInVarIndex]; + std::string result = "((" + varName + " & " + mask + ") != 0)"; + return result; +} + +std::string GenerateSetBitInternal(const std::string& prefix, int bitIndex) { + std::string varName = prefix + GetBitFieldNameForBit(bitIndex); + int bitInVarIndex = bitIndex % 32; + + std::string mask = bit_masks[bitInVarIndex]; + std::string result = varName + " |= " + mask; + return result; +} + +} // namespace + +std::string GenerateGetBit(int bitIndex) { + return GenerateGetBitInternal("", bitIndex); +} + +std::string GenerateSetBit(int bitIndex) { + return GenerateSetBitInternal("", bitIndex); +} + +std::string GenerateClearBit(int bitIndex) { + std::string varName = GetBitFieldNameForBit(bitIndex); + int bitInVarIndex = bitIndex % 32; + + std::string mask = bit_masks[bitInVarIndex]; + std::string result = varName + " = (" + varName + " & ~" + mask + ")"; + return result; +} + +std::string GenerateGetBitFromLocal(int bitIndex) { + return GenerateGetBitInternal("from_", bitIndex); +} + +std::string GenerateSetBitToLocal(int bitIndex) { + return GenerateSetBitInternal("to_", bitIndex); +} + +std::string GenerateGetBitMutableLocal(int bitIndex) { + return GenerateGetBitInternal("mutable_", bitIndex); +} + +std::string GenerateSetBitMutableLocal(int bitIndex) { + return GenerateSetBitInternal("mutable_", bitIndex); +} + +bool IsReferenceType(JavaType type) { + switch (type) { + case JAVATYPE_INT: + return false; + case JAVATYPE_LONG: + return false; + case JAVATYPE_FLOAT: + return false; + case JAVATYPE_DOUBLE: + return false; + case JAVATYPE_BOOLEAN: + return false; + case JAVATYPE_STRING: + return true; + case JAVATYPE_BYTES: + return true; + case JAVATYPE_ENUM: + return true; + case JAVATYPE_MESSAGE: + return true; + + // No default because we want the compiler to complain if any new + // JavaTypes are added. + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return false; +} + +const char* GetCapitalizedType(const FieldDescriptor* field, bool immutable) { + switch (GetType(field)) { + case FieldDescriptor::TYPE_INT32: + return "Int32"; + case FieldDescriptor::TYPE_UINT32: + return "UInt32"; + case FieldDescriptor::TYPE_SINT32: + return "SInt32"; + case FieldDescriptor::TYPE_FIXED32: + return "Fixed32"; + case FieldDescriptor::TYPE_SFIXED32: + return "SFixed32"; + case FieldDescriptor::TYPE_INT64: + return "Int64"; + case FieldDescriptor::TYPE_UINT64: + return "UInt64"; + case FieldDescriptor::TYPE_SINT64: + return "SInt64"; + case FieldDescriptor::TYPE_FIXED64: + return "Fixed64"; + case FieldDescriptor::TYPE_SFIXED64: + return "SFixed64"; + case FieldDescriptor::TYPE_FLOAT: + return "Float"; + case FieldDescriptor::TYPE_DOUBLE: + return "Double"; + case FieldDescriptor::TYPE_BOOL: + return "Bool"; + case FieldDescriptor::TYPE_STRING: + return "String"; + case FieldDescriptor::TYPE_BYTES: { + return "Bytes"; + } + case FieldDescriptor::TYPE_ENUM: + return "Enum"; + case FieldDescriptor::TYPE_GROUP: + return "Group"; + case FieldDescriptor::TYPE_MESSAGE: + return "Message"; + + // No default because we want the compiler to complain if any new + // types are added. + } + + GOOGLE_LOG(FATAL) << "Can't get here."; + return NULL; +} + +// For encodings with fixed sizes, returns that size in bytes. Otherwise +// returns -1. +int FixedSize(FieldDescriptor::Type type) { + switch (type) { + case FieldDescriptor::TYPE_INT32: + return -1; + case FieldDescriptor::TYPE_INT64: + return -1; + case FieldDescriptor::TYPE_UINT32: + return -1; + case FieldDescriptor::TYPE_UINT64: + return -1; + case FieldDescriptor::TYPE_SINT32: + return -1; + case FieldDescriptor::TYPE_SINT64: + return -1; + case FieldDescriptor::TYPE_FIXED32: + return WireFormatLite::kFixed32Size; + case FieldDescriptor::TYPE_FIXED64: + return WireFormatLite::kFixed64Size; + case FieldDescriptor::TYPE_SFIXED32: + return WireFormatLite::kSFixed32Size; + case FieldDescriptor::TYPE_SFIXED64: + return WireFormatLite::kSFixed64Size; + case FieldDescriptor::TYPE_FLOAT: + return WireFormatLite::kFloatSize; + case FieldDescriptor::TYPE_DOUBLE: + return WireFormatLite::kDoubleSize; + + case FieldDescriptor::TYPE_BOOL: + return WireFormatLite::kBoolSize; + case FieldDescriptor::TYPE_ENUM: + return -1; + + case FieldDescriptor::TYPE_STRING: + return -1; + case FieldDescriptor::TYPE_BYTES: + return -1; + case FieldDescriptor::TYPE_GROUP: + return -1; + case FieldDescriptor::TYPE_MESSAGE: + return -1; + + // No default because we want the compiler to complain if any new + // types are added. + } + GOOGLE_LOG(FATAL) << "Can't get here."; + return -1; +} + +// Sort the fields of the given Descriptor by number into a new[]'d array +// and return it. The caller should delete the returned array. +const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) { + const FieldDescriptor** fields = + new const FieldDescriptor*[descriptor->field_count()]; + for (int i = 0; i < descriptor->field_count(); i++) { + fields[i] = descriptor->field(i); + } + std::sort(fields, fields + descriptor->field_count(), + FieldOrderingByNumber()); + return fields; +} + +// Returns true if the message type has any required fields. If it doesn't, +// we can optimize out calls to its isInitialized() method. +// +// already_seen is used to avoid checking the same type multiple times +// (and also to protect against recursion). +bool HasRequiredFields(const Descriptor* type, + std::unordered_set<const Descriptor*>* already_seen) { + if (already_seen->count(type) > 0) { + // The type is already in cache. This means that either: + // a. The type has no required fields. + // b. We are in the midst of checking if the type has required fields, + // somewhere up the stack. In this case, we know that if the type + // has any required fields, they'll be found when we return to it, + // and the whole call to HasRequiredFields() will return true. + // Therefore, we don't have to check if this type has required fields + // here. + return false; + } + already_seen->insert(type); + + // If the type has extensions, an extension with message type could contain + // required fields, so we have to be conservative and assume such an + // extension exists. + if (type->extension_range_count() > 0) return true; + + for (int i = 0; i < type->field_count(); i++) { + const FieldDescriptor* field = type->field(i); + if (field->is_required()) { + return true; + } + if (GetJavaType(field) == JAVATYPE_MESSAGE) { + if (HasRequiredFields(field->message_type(), already_seen)) { + return true; + } + } + } + + return false; +} + +bool HasRequiredFields(const Descriptor* type) { + std::unordered_set<const Descriptor*> already_seen; + return HasRequiredFields(type, &already_seen); +} + +bool HasRepeatedFields(const Descriptor* descriptor) { + for (int i = 0; i < descriptor->field_count(); ++i) { + const FieldDescriptor* field = descriptor->field(i); + if (field->is_repeated()) { + return true; + } + } + return false; +} + +// Encode an unsigned 32-bit value into a sequence of UTF-16 characters. +// +// If the value is in [0x0000, 0xD7FF], we encode it with a single character +// with the same numeric value. +// +// If the value is larger than 0xD7FF, we encode its lowest 13 bits into a +// character in the range [0xE000, 0xFFFF] by combining these 13 bits with +// 0xE000 using logic-or. Then we shift the value to the right by 13 bits, and +// encode the remaining value by repeating this same process until we get to +// a value in [0x0000, 0xD7FF] where we will encode it using a character with +// the same numeric value. +// +// Note that we only use code points in [0x0000, 0xD7FF] and [0xE000, 0xFFFF]. +// There will be no surrogate pairs in the encoded character sequence. +void WriteUInt32ToUtf16CharSequence(uint32_t number, + std::vector<uint16_t>* output) { + // For values in [0x0000, 0xD7FF], only use one char to encode it. + if (number < 0xD800) { + output->push_back(static_cast<uint16_t>(number)); + return; + } + // Encode into multiple chars. All except the last char will be in the range + // [0xE000, 0xFFFF], and the last char will be in the range [0x0000, 0xD7FF]. + // Note that we don't use any value in range [0xD800, 0xDFFF] because they + // have to come in pairs and the encoding is just more space-efficient w/o + // them. + while (number >= 0xD800) { + // [0xE000, 0xFFFF] can represent 13 bits of info. + output->push_back(static_cast<uint16_t>(0xE000 | (number & 0x1FFF))); + number >>= 13; + } + output->push_back(static_cast<uint16_t>(number)); +} + +int GetExperimentalJavaFieldTypeForSingular(const FieldDescriptor* field) { + // j/c/g/protobuf/FieldType.java lists field types in a slightly different + // order from FieldDescriptor::Type so we can't do a simple cast. + // + // TODO(xiaofeng): Make j/c/g/protobuf/FieldType.java follow the same order. + int result = field->type(); + if (result == FieldDescriptor::TYPE_GROUP) { + return 17; + } else if (result < FieldDescriptor::TYPE_GROUP) { + return result - 1; + } else { + return result - 2; + } +} + +int GetExperimentalJavaFieldTypeForRepeated(const FieldDescriptor* field) { + if (field->type() == FieldDescriptor::TYPE_GROUP) { + return 49; + } else { + return GetExperimentalJavaFieldTypeForSingular(field) + 18; + } +} + +int GetExperimentalJavaFieldTypeForPacked(const FieldDescriptor* field) { + int result = field->type(); + if (result < FieldDescriptor::TYPE_STRING) { + return result + 34; + } else if (result > FieldDescriptor::TYPE_BYTES) { + return result + 30; + } else { + GOOGLE_LOG(FATAL) << field->full_name() << " can't be packed."; + return 0; + } +} + +int GetExperimentalJavaFieldType(const FieldDescriptor* field) { + static const int kMapFieldType = 50; + static const int kOneofFieldTypeOffset = 51; + static const int kRequiredBit = 0x100; + static const int kUtf8CheckBit = 0x200; + static const int kCheckInitialized = 0x400; + static const int kMapWithProto2EnumValue = 0x800; + static const int kHasHasBit = 0x1000; + int extra_bits = field->is_required() ? kRequiredBit : 0; + if (field->type() == FieldDescriptor::TYPE_STRING && CheckUtf8(field)) { + extra_bits |= kUtf8CheckBit; + } + if (field->is_required() || (GetJavaType(field) == JAVATYPE_MESSAGE && + HasRequiredFields(field->message_type()))) { + extra_bits |= kCheckInitialized; + } + if (HasHasbit(field)) { + extra_bits |= kHasHasBit; + } + + if (field->is_map()) { + if (!SupportUnknownEnumValue(field)) { + const FieldDescriptor* value = + field->message_type()->FindFieldByName("value"); + if (GetJavaType(value) == JAVATYPE_ENUM) { + extra_bits |= kMapWithProto2EnumValue; + } + } + return kMapFieldType | extra_bits; + } else if (field->is_packed()) { + return GetExperimentalJavaFieldTypeForPacked(field); + } else if (field->is_repeated()) { + return GetExperimentalJavaFieldTypeForRepeated(field) | extra_bits; + } else if (IsRealOneof(field)) { + return (GetExperimentalJavaFieldTypeForSingular(field) + + kOneofFieldTypeOffset) | + extra_bits; + } else { + return GetExperimentalJavaFieldTypeForSingular(field) | extra_bits; + } +} + +// Escape a UTF-16 character to be embedded in a Java string. +void EscapeUtf16ToString(uint16_t code, std::string* output) { + if (code == '\t') { + output->append("\\t"); + } else if (code == '\b') { + output->append("\\b"); + } else if (code == '\n') { + output->append("\\n"); + } else if (code == '\r') { + output->append("\\r"); + } else if (code == '\f') { + output->append("\\f"); + } else if (code == '\'') { + output->append("\\'"); + } else if (code == '\"') { + output->append("\\\""); + } else if (code == '\\') { + output->append("\\\\"); + } else if (code >= 0x20 && code <= 0x7f) { + output->push_back(static_cast<char>(code)); + } else { + output->append(StringPrintf("\\u%04x", code)); + } +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_helpers.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_helpers.h new file mode 100644 index 00000000..428aa254 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_helpers.h @@ -0,0 +1,459 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__ + +#include <cstdint> +#include <string> + +#include <compiler/java/java_context.h> +#include <descriptor.pb.h> +#include <io/printer.h> +#include <descriptor.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +// Commonly-used separator comments. Thick is a line of '=', thin is a line +// of '-'. +extern const char kThickSeparator[]; +extern const char kThinSeparator[]; + +bool IsForbiddenKotlin(const std::string& field_name); + +// If annotation_file is non-empty, prints a javax.annotation.Generated +// annotation to the given Printer. annotation_file will be referenced in the +// annotation's comments field. delimiter should be the Printer's delimiter +// character. annotation_file will be included verbatim into a Java literal +// string, so it should not contain quotes or invalid Java escape sequences; +// however, these are unlikely to appear in practice, as the value of +// annotation_file should be generated from the filename of the source file +// being annotated (which in turn must be a Java identifier plus ".java"). +void PrintGeneratedAnnotation(io::Printer* printer, char delimiter = '$', + const std::string& annotation_file = ""); + +// If a GeneratedMessageLite contains non-lite enums, then its verifier +// must be instantiated inline, rather than retrieved from the enum class. +void PrintEnumVerifierLogic(io::Printer* printer, + const FieldDescriptor* descriptor, + const std::map<std::string, std::string>& variables, + const char* var_name, + const char* terminating_string, bool enforce_lite); + +// Converts a name to camel-case. If cap_first_letter is true, capitalize the +// first letter. +std::string ToCamelCase(const std::string& input, bool lower_first); + +char ToUpperCh(char ch); +char ToLowerCh(char ch); + +// Converts a name to camel-case. If cap_first_letter is true, capitalize the +// first letter. +std::string UnderscoresToCamelCase(const std::string& name, + bool cap_first_letter); +// Converts the field's name to camel-case, e.g. "foo_bar_baz" becomes +// "fooBarBaz" or "FooBarBaz", respectively. +std::string UnderscoresToCamelCase(const FieldDescriptor* field); +std::string UnderscoresToCapitalizedCamelCase(const FieldDescriptor* field); + +// Similar, but for method names. (Typically, this merely has the effect +// of lower-casing the first letter of the name.) +std::string UnderscoresToCamelCase(const MethodDescriptor* method); + +// Same as UnderscoresToCamelCase, but checks for reserved keywords +std::string UnderscoresToCamelCaseCheckReserved(const FieldDescriptor* field); + +// Similar to UnderscoresToCamelCase, but guarantees that the result is a +// complete Java identifier by adding a _ if needed. +std::string CamelCaseFieldName(const FieldDescriptor* field); + +// Get an identifier that uniquely identifies this type within the file. +// This is used to declare static variables related to this type at the +// outermost file scope. +std::string UniqueFileScopeIdentifier(const Descriptor* descriptor); + +// Gets the unqualified class name for the file. For each .proto file, there +// will be one Java class containing all the immutable messages and another +// Java class containing all the mutable messages. +// TODO(xiaofeng): remove the default value after updating client code. +std::string FileClassName(const FileDescriptor* file, bool immutable = true); + +// Returns the file's Java package name. +std::string FileJavaPackage(const FileDescriptor* file, bool immutable); + +// Returns output directory for the given package name. +std::string JavaPackageToDir(std::string package_name); + +// Comma-separate list of option-specified interfaces implemented by the +// Message, to follow the "implements" declaration of the Message definition. +std::string ExtraMessageInterfaces(const Descriptor* descriptor); +// Comma-separate list of option-specified interfaces implemented by the +// MutableMessage, to follow the "implements" declaration of the MutableMessage +// definition. +std::string ExtraMutableMessageInterfaces(const Descriptor* descriptor); +// Comma-separate list of option-specified interfaces implemented by the +// Builder, to follow the "implements" declaration of the Builder definition. +std::string ExtraBuilderInterfaces(const Descriptor* descriptor); +// Comma-separate list of option-specified interfaces extended by the +// MessageOrBuilder, to follow the "extends" declaration of the +// MessageOrBuilder definition. +std::string ExtraMessageOrBuilderInterfaces(const Descriptor* descriptor); + +// Get the unqualified Java class name for mutable messages. i.e. without +// package or outer classnames. +inline std::string ShortMutableJavaClassName(const Descriptor* descriptor) { + return descriptor->name(); +} + +// Whether the given descriptor is for one of the core descriptor protos. We +// cannot currently use the new runtime with core protos since there is a +// bootstrapping problem with obtaining their descriptors. +inline bool IsDescriptorProto(const Descriptor* descriptor) { + return descriptor->file()->name() == "net/proto2/proto/descriptor.proto" || + descriptor->file()->name() == "google/protobuf/descriptor.proto"; +} + +// Returns the stored type string used by the experimental runtime for oneof +// fields. +std::string GetOneofStoredType(const FieldDescriptor* field); + + +// Whether we should generate multiple java files for messages. +inline bool MultipleJavaFiles(const FileDescriptor* descriptor, + bool immutable) { + (void)immutable; + return descriptor->options().java_multiple_files(); +} + + +// Returns true if `descriptor` will be written to its own .java file. +// `immutable` should be set to true if we're generating for the immutable API. +template <typename Descriptor> +bool IsOwnFile(const Descriptor* descriptor, bool immutable) { + return descriptor->containing_type() == NULL && + MultipleJavaFiles(descriptor->file(), immutable); +} + +template <> +inline bool IsOwnFile(const ServiceDescriptor* descriptor, bool immutable) { + return MultipleJavaFiles(descriptor->file(), immutable); +} + +// If `descriptor` describes an object with its own .java file, +// returns the name (relative to that .java file) of the file that stores +// annotation data for that descriptor. `suffix` is usually empty, but may +// (e.g.) be "OrBuilder" for some generated interfaces. +template <typename Descriptor> +std::string AnnotationFileName(const Descriptor* descriptor, + const std::string& suffix) { + return descriptor->name() + suffix + ".java.pb.meta"; +} + +template <typename Descriptor> +void MaybePrintGeneratedAnnotation(Context* context, io::Printer* printer, + Descriptor* descriptor, bool immutable, + const std::string& suffix = "") { + if (IsOwnFile(descriptor, immutable)) { + PrintGeneratedAnnotation(printer, '$', + context->options().annotate_code + ? AnnotationFileName(descriptor, suffix) + : ""); + } +} + +// Get the unqualified name that should be used for a field's field +// number constant. +std::string FieldConstantName(const FieldDescriptor* field); + +// Returns the type of the FieldDescriptor. +// This does nothing interesting for the open source release, but is used for +// hacks that improve compatibility with version 1 protocol buffers at Google. +FieldDescriptor::Type GetType(const FieldDescriptor* field); + +enum JavaType { + JAVATYPE_INT, + JAVATYPE_LONG, + JAVATYPE_FLOAT, + JAVATYPE_DOUBLE, + JAVATYPE_BOOLEAN, + JAVATYPE_STRING, + JAVATYPE_BYTES, + JAVATYPE_ENUM, + JAVATYPE_MESSAGE +}; + +JavaType GetJavaType(const FieldDescriptor* field); + +const char* PrimitiveTypeName(JavaType type); + +// Get the fully-qualified class name for a boxed primitive type, e.g. +// "java.lang.Integer" for JAVATYPE_INT. Returns NULL for enum and message +// types. +const char* BoxedPrimitiveTypeName(JavaType type); + +// Kotlin source does not distinguish between primitives and non-primitives, +// but does use Kotlin-specific qualified types for them. +const char* KotlinTypeName(JavaType type); + +// Get the name of the java enum constant representing this type. E.g., +// "INT32" for FieldDescriptor::TYPE_INT32. The enum constant's full +// name is "com.google.protobuf.WireFormat.FieldType.INT32". +const char* FieldTypeName(const FieldDescriptor::Type field_type); + +class ClassNameResolver; +std::string DefaultValue(const FieldDescriptor* field, bool immutable, + ClassNameResolver* name_resolver); +inline std::string ImmutableDefaultValue(const FieldDescriptor* field, + ClassNameResolver* name_resolver) { + return DefaultValue(field, true, name_resolver); +} +bool IsDefaultValueJavaDefault(const FieldDescriptor* field); +bool IsByteStringWithCustomDefaultValue(const FieldDescriptor* field); + +// Does this message class have descriptor and reflection methods? +inline bool HasDescriptorMethods(const Descriptor* /* descriptor */, + bool enforce_lite) { + return !enforce_lite; +} +inline bool HasDescriptorMethods(const EnumDescriptor* /* descriptor */, + bool enforce_lite) { + return !enforce_lite; +} +inline bool HasDescriptorMethods(const FileDescriptor* /* descriptor */, + bool enforce_lite) { + return !enforce_lite; +} + +// Should we generate generic services for this file? +inline bool HasGenericServices(const FileDescriptor* file, bool enforce_lite) { + return file->service_count() > 0 && + HasDescriptorMethods(file, enforce_lite) && + file->options().java_generic_services(); +} + +// Methods for shared bitfields. + +// Gets the name of the shared bitfield for the given index. +std::string GetBitFieldName(int index); + +// Gets the name of the shared bitfield for the given bit index. +// Effectively, GetBitFieldName(bitIndex / 32) +std::string GetBitFieldNameForBit(int bitIndex); + +// Generates the java code for the expression that returns the boolean value +// of the bit of the shared bitfields for the given bit index. +// Example: "((bitField1_ & 0x04) == 0x04)" +std::string GenerateGetBit(int bitIndex); + +// Generates the java code for the expression that sets the bit of the shared +// bitfields for the given bit index. +// Example: "bitField1_ = (bitField1_ | 0x04)" +std::string GenerateSetBit(int bitIndex); + +// Generates the java code for the expression that clears the bit of the shared +// bitfields for the given bit index. +// Example: "bitField1_ = (bitField1_ & ~0x04)" +std::string GenerateClearBit(int bitIndex); + +// Does the same as GenerateGetBit but operates on the bit field on a local +// variable. This is used by the builder to copy the value in the builder to +// the message. +// Example: "((from_bitField1_ & 0x04) == 0x04)" +std::string GenerateGetBitFromLocal(int bitIndex); + +// Does the same as GenerateSetBit but operates on the bit field on a local +// variable. This is used by the builder to copy the value in the builder to +// the message. +// Example: "to_bitField1_ = (to_bitField1_ | 0x04)" +std::string GenerateSetBitToLocal(int bitIndex); + +// Does the same as GenerateGetBit but operates on the bit field on a local +// variable. This is used by the parsing constructor to record if a repeated +// field is mutable. +// Example: "((mutable_bitField1_ & 0x04) == 0x04)" +std::string GenerateGetBitMutableLocal(int bitIndex); + +// Does the same as GenerateSetBit but operates on the bit field on a local +// variable. This is used by the parsing constructor to record if a repeated +// field is mutable. +// Example: "mutable_bitField1_ = (mutable_bitField1_ | 0x04)" +std::string GenerateSetBitMutableLocal(int bitIndex); + +// Returns whether the JavaType is a reference type. +bool IsReferenceType(JavaType type); + +// Returns the capitalized name for calling relative functions in +// CodedInputStream +const char* GetCapitalizedType(const FieldDescriptor* field, bool immutable); + +// For encodings with fixed sizes, returns that size in bytes. Otherwise +// returns -1. +int FixedSize(FieldDescriptor::Type type); + +// Comparators used to sort fields in MessageGenerator +struct FieldOrderingByNumber { + inline bool operator()(const FieldDescriptor* a, + const FieldDescriptor* b) const { + return a->number() < b->number(); + } +}; + +struct ExtensionRangeOrdering { + bool operator()(const Descriptor::ExtensionRange* a, + const Descriptor::ExtensionRange* b) const { + return a->start < b->start; + } +}; + +// Sort the fields of the given Descriptor by number into a new[]'d array +// and return it. The caller should delete the returned array. +const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor); + +// Does this message class have any packed fields? +inline bool HasPackedFields(const Descriptor* descriptor) { + for (int i = 0; i < descriptor->field_count(); i++) { + if (descriptor->field(i)->is_packed()) { + return true; + } + } + return false; +} + +// Check a message type and its sub-message types recursively to see if any of +// them has a required field. Return true if a required field is found. +bool HasRequiredFields(const Descriptor* descriptor); + +inline bool IsProto2(const FileDescriptor* descriptor) { + return descriptor->syntax() == FileDescriptor::SYNTAX_PROTO2; +} + +inline bool IsRealOneof(const FieldDescriptor* descriptor) { + return descriptor->containing_oneof() && + !descriptor->containing_oneof()->is_synthetic(); +} + +inline bool HasHazzer(const FieldDescriptor* descriptor) { + return !descriptor->is_repeated() && + (descriptor->message_type() || descriptor->has_optional_keyword() || + IsProto2(descriptor->file()) || IsRealOneof(descriptor)); +} + +inline bool HasHasbit(const FieldDescriptor* descriptor) { + // Note that currently message fields inside oneofs have hasbits. This is + // surprising, as the oneof case should avoid any need for a hasbit. But if + // you change this method to remove hasbits for oneofs, a few tests fail. + // TODO(b/124347790): remove hasbits for oneofs + return !descriptor->is_repeated() && + (descriptor->has_optional_keyword() || IsProto2(descriptor->file())); +} + +// Whether generate classes expose public PARSER instances. +inline bool ExposePublicParser(const FileDescriptor* descriptor) { + // TODO(liujisi): Mark the PARSER private in 3.1.x releases. + return descriptor->syntax() == FileDescriptor::SYNTAX_PROTO2; +} + +// Whether unknown enum values are kept (i.e., not stored in UnknownFieldSet +// but in the message and can be queried using additional getters that return +// ints. +inline bool SupportUnknownEnumValue(const FileDescriptor* descriptor) { + return descriptor->syntax() == FileDescriptor::SYNTAX_PROTO3; +} + +inline bool SupportUnknownEnumValue(const FieldDescriptor* field) { + return field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3; +} + +// Check whether a message has repeated fields. +bool HasRepeatedFields(const Descriptor* descriptor); + +inline bool IsMapEntry(const Descriptor* descriptor) { + return descriptor->options().map_entry(); +} + +inline bool IsMapField(const FieldDescriptor* descriptor) { + return descriptor->is_map(); +} + +inline bool IsAnyMessage(const Descriptor* descriptor) { + return descriptor->full_name() == "google.protobuf.Any"; +} + +inline bool IsWrappersProtoFile(const FileDescriptor* descriptor) { + return descriptor->name() == "google/protobuf/wrappers.proto"; +} + +inline bool CheckUtf8(const FieldDescriptor* descriptor) { + return descriptor->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 || + descriptor->file()->options().java_string_check_utf8(); +} + +inline std::string GeneratedCodeVersionSuffix() { + return "V3"; +} + +void WriteUInt32ToUtf16CharSequence(uint32_t number, + std::vector<uint16_t>* output); + +inline void WriteIntToUtf16CharSequence(int value, + std::vector<uint16_t>* output) { + WriteUInt32ToUtf16CharSequence(static_cast<uint32_t>(value), output); +} + +// Escape a UTF-16 character so it can be embedded in a Java string literal. +void EscapeUtf16ToString(uint16_t code, std::string* output); + +// Only the lowest two bytes of the return value are used. The lowest byte +// is the integer value of a j/c/g/protobuf/FieldType enum. For the other +// byte: +// bit 0: whether the field is required. +// bit 1: whether the field requires UTF-8 validation. +// bit 2: whether the field needs isInitialized check. +// bit 3: whether the field is a map field with proto2 enum value. +// bits 4-7: unused +int GetExperimentalJavaFieldType(const FieldDescriptor* field); + +// To get the total number of entries need to be built for experimental runtime +// and the first field number that are not in the table part +std::pair<int, int> GetTableDrivenNumberOfEntriesAndLookUpStartFieldNumber( + const FieldDescriptor** fields, int count); +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_HELPERS_H__ diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_kotlin_generator.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_kotlin_generator.cc new file mode 100644 index 00000000..d043ed80 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_kotlin_generator.cc @@ -0,0 +1,162 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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. + +#include <compiler/java/java_kotlin_generator.h> + +#include <compiler/java/java_file.h> +#include <compiler/java/java_helpers.h> +#include <compiler/java/java_options.h> +#include <compiler/java/java_generator.h> +#include <compiler/code_generator.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +KotlinGenerator::KotlinGenerator() {} +KotlinGenerator::~KotlinGenerator() {} + +uint64_t KotlinGenerator::GetSupportedFeatures() const { + return CodeGenerator::Feature::FEATURE_PROTO3_OPTIONAL; +} + +bool KotlinGenerator::Generate(const FileDescriptor* file, + const std::string& parameter, + GeneratorContext* context, + std::string* error) const { + // ----------------------------------------------------------------- + // parse generator options + + std::vector<std::pair<std::string, std::string> > options; + ParseGeneratorParameter(parameter, &options); + Options file_options; + + for (auto& option : options) { + if (option.first == "output_list_file") { + file_options.output_list_file = option.second; + } else if (option.first == "immutable") { + file_options.generate_immutable_code = true; + } else if (option.first == "mutable") { + *error = "Mutable not supported by Kotlin generator"; + return false; + } else if (option.first == "shared") { + file_options.generate_shared_code = true; + } else if (option.first == "lite") { + file_options.enforce_lite = true; + } else if (option.first == "annotate_code") { + file_options.annotate_code = true; + } else if (option.first == "annotation_list_file") { + file_options.annotation_list_file = option.second; + } else { + *error = "Unknown generator option: " + option.first; + return false; + } + } + + // By default we generate immutable code and shared code for immutable API. + if (!file_options.generate_immutable_code && + !file_options.generate_shared_code) { + file_options.generate_immutable_code = true; + file_options.generate_shared_code = true; + } + + std::vector<std::string> all_files; + std::vector<std::string> all_annotations; + + std::unique_ptr<FileGenerator> file_generator; + if (file_options.generate_immutable_code) { + file_generator.reset( + new FileGenerator(file, file_options, /* immutable_api = */ true)); + } + + if (!file_generator->Validate(error)) { + return false; + } + + auto open_file = [context](const std::string& filename) { + return std::unique_ptr<io::ZeroCopyOutputStream>(context->Open(filename)); + }; + std::string package_dir = JavaPackageToDir(file_generator->java_package()); + std::string kotlin_filename = package_dir; + kotlin_filename += file_generator->GetKotlinClassname(); + kotlin_filename += ".kt"; + all_files.push_back(kotlin_filename); + std::string info_full_path = kotlin_filename + ".pb.meta"; + if (file_options.annotate_code) { + all_annotations.push_back(info_full_path); + } + + // Generate main kotlin file. + auto output = open_file(kotlin_filename); + GeneratedCodeInfo annotations; + io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector( + &annotations); + io::Printer printer( + output.get(), '$', + file_options.annotate_code ? &annotation_collector : nullptr); + + file_generator->GenerateKotlinSiblings(package_dir, context, &all_files, + &all_annotations); + + if (file_options.annotate_code) { + auto info_output = open_file(info_full_path); + annotations.SerializeToZeroCopyStream(info_output.get()); + } + + // Generate output list if requested. + if (!file_options.output_list_file.empty()) { + // Generate output list. This is just a simple text file placed in a + // deterministic location which lists the .kt files being generated. + auto srclist_raw_output = open_file(file_options.output_list_file); + io::Printer srclist_printer(srclist_raw_output.get(), '$'); + for (auto& all_file : all_files) { + srclist_printer.Print("$filename$\n", "filename", all_file); + } + } + + if (!file_options.annotation_list_file.empty()) { + // Generate output list. This is just a simple text file placed in a + // deterministic location which lists the .kt files being generated. + auto annotation_list_raw_output = + open_file(file_options.annotation_list_file); + io::Printer annotation_list_printer(annotation_list_raw_output.get(), '$'); + for (auto& all_annotation : all_annotations) { + annotation_list_printer.Print("$filename$\n", "filename", all_annotation); + } + } + + return true; +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_kotlin_generator.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_kotlin_generator.h new file mode 100644 index 00000000..87ae2507 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_kotlin_generator.h @@ -0,0 +1,72 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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. + +// Generates Kotlin code for a given .proto file. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_KOTLIN_GENERATOR_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_KOTLIN_GENERATOR_H__ + +#include <string> + +#include <compiler/code_generator.h> +#include <port_def.inc> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +// CodeGenerator implementation which generates Kotlin code. If you create your +// own protocol compiler binary and you want it to support Kotlin output, you +// can do so by registering an instance of this CodeGenerator with the +// CommandLineInterface in your main() function. +class PROTOC_EXPORT KotlinGenerator : public CodeGenerator { + public: + KotlinGenerator(); + ~KotlinGenerator() override; + + // implements CodeGenerator ---------------------------------------- + bool Generate(const FileDescriptor* file, const std::string& parameter, + GeneratorContext* context, std::string* error) const override; + + uint64_t GetSupportedFeatures() const override; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(KotlinGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +#include <port_undef.inc> + +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_KOTLIN_GENERATOR_H__ diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_map_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_map_field.cc new file mode 100644 index 00000000..602e5954 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_map_field.cc @@ -0,0 +1,876 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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. + +#include <compiler/java/java_map_field.h> + +#include <compiler/java/java_context.h> +#include <compiler/java/java_doc_comment.h> +#include <compiler/java/java_helpers.h> +#include <compiler/java/java_name_resolver.h> +#include <io/printer.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +namespace { + +const FieldDescriptor* KeyField(const FieldDescriptor* descriptor) { + GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, descriptor->type()); + const Descriptor* message = descriptor->message_type(); + GOOGLE_CHECK(message->options().map_entry()); + return message->FindFieldByName("key"); +} + +const FieldDescriptor* ValueField(const FieldDescriptor* descriptor) { + GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, descriptor->type()); + const Descriptor* message = descriptor->message_type(); + GOOGLE_CHECK(message->options().map_entry()); + return message->FindFieldByName("value"); +} + +std::string TypeName(const FieldDescriptor* field, + ClassNameResolver* name_resolver, bool boxed) { + if (GetJavaType(field) == JAVATYPE_MESSAGE) { + return name_resolver->GetImmutableClassName(field->message_type()); + } else if (GetJavaType(field) == JAVATYPE_ENUM) { + return name_resolver->GetImmutableClassName(field->enum_type()); + } else { + return boxed ? BoxedPrimitiveTypeName(GetJavaType(field)) + : PrimitiveTypeName(GetJavaType(field)); + } +} + +std::string KotlinTypeName(const FieldDescriptor* field, + ClassNameResolver* name_resolver) { + if (GetJavaType(field) == JAVATYPE_MESSAGE) { + return name_resolver->GetImmutableClassName(field->message_type()); + } else if (GetJavaType(field) == JAVATYPE_ENUM) { + return name_resolver->GetImmutableClassName(field->enum_type()); + } else { + return KotlinTypeName(GetJavaType(field)); + } +} + +std::string WireType(const FieldDescriptor* field) { + return "com.google.protobuf.WireFormat.FieldType." + + std::string(FieldTypeName(field->type())); +} + +void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, + int builderBitIndex, const FieldGeneratorInfo* info, + Context* context, + std::map<std::string, std::string>* variables) { + SetCommonFieldVariables(descriptor, info, variables); + ClassNameResolver* name_resolver = context->GetNameResolver(); + + (*variables)["type"] = + name_resolver->GetImmutableClassName(descriptor->message_type()); + const FieldDescriptor* key = KeyField(descriptor); + const FieldDescriptor* value = ValueField(descriptor); + const JavaType keyJavaType = GetJavaType(key); + const JavaType valueJavaType = GetJavaType(value); + + (*variables)["key_type"] = TypeName(key, name_resolver, false); + std::string boxed_key_type = TypeName(key, name_resolver, true); + (*variables)["boxed_key_type"] = boxed_key_type; + (*variables)["kt_key_type"] = KotlinTypeName(key, name_resolver); + (*variables)["kt_value_type"] = KotlinTypeName(value, name_resolver); + // Used for calling the serialization function. + (*variables)["short_key_type"] = + boxed_key_type.substr(boxed_key_type.rfind('.') + 1); + (*variables)["key_wire_type"] = WireType(key); + (*variables)["key_default_value"] = DefaultValue(key, true, name_resolver); + (*variables)["key_null_check"] = + IsReferenceType(keyJavaType) + ? "if (key == null) { throw new NullPointerException(\"map key\"); }" + : ""; + (*variables)["value_null_check"] = + valueJavaType != JAVATYPE_ENUM && IsReferenceType(valueJavaType) + ? "if (value == null) {\n" + " throw new NullPointerException(\"map value\");\n" + "}\n" + : ""; + if (valueJavaType == JAVATYPE_ENUM) { + // We store enums as Integers internally. + (*variables)["value_type"] = "int"; + (*variables)["boxed_value_type"] = "java.lang.Integer"; + (*variables)["value_wire_type"] = WireType(value); + (*variables)["value_default_value"] = + DefaultValue(value, true, name_resolver) + ".getNumber()"; + + (*variables)["value_enum_type"] = TypeName(value, name_resolver, false); + + if (SupportUnknownEnumValue(descriptor->file())) { + // Map unknown values to a special UNRECOGNIZED value if supported. + (*variables)["unrecognized_value"] = + (*variables)["value_enum_type"] + ".UNRECOGNIZED"; + } else { + // Map unknown values to the default value if we don't have UNRECOGNIZED. + (*variables)["unrecognized_value"] = + DefaultValue(value, true, name_resolver); + } + } else { + (*variables)["value_type"] = TypeName(value, name_resolver, false); + (*variables)["boxed_value_type"] = TypeName(value, name_resolver, true); + (*variables)["value_wire_type"] = WireType(value); + (*variables)["value_default_value"] = + DefaultValue(value, true, name_resolver); + } + (*variables)["type_parameters"] = + (*variables)["boxed_key_type"] + ", " + (*variables)["boxed_value_type"]; + // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported + // by the proto compiler + (*variables)["deprecation"] = + descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; + (*variables)["kt_deprecation"] = + descriptor->options().deprecated() + ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] + + " is deprecated\") " + : ""; + (*variables)["on_changed"] = "onChanged();"; + + // For repeated fields, one bit is used for whether the array is immutable + // in the parsing constructor. + (*variables)["get_mutable_bit_parser"] = + GenerateGetBitMutableLocal(builderBitIndex); + (*variables)["set_mutable_bit_parser"] = + GenerateSetBitMutableLocal(builderBitIndex); + + (*variables)["default_entry"] = + (*variables)["capitalized_name"] + "DefaultEntryHolder.defaultEntry"; + (*variables)["map_field_parameter"] = (*variables)["default_entry"]; + (*variables)["descriptor"] = + name_resolver->GetImmutableClassName(descriptor->file()) + ".internal_" + + UniqueFileScopeIdentifier(descriptor->message_type()) + "_descriptor, "; + (*variables)["ver"] = GeneratedCodeVersionSuffix(); +} + +} // namespace + +ImmutableMapFieldGenerator::ImmutableMapFieldGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, + Context* context) + : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) { + SetMessageVariables(descriptor, messageBitIndex, builderBitIndex, + context->GetFieldGeneratorInfo(descriptor), context, + &variables_); +} + +ImmutableMapFieldGenerator::~ImmutableMapFieldGenerator() {} + +int ImmutableMapFieldGenerator::GetNumBitsForMessage() const { return 0; } + +int ImmutableMapFieldGenerator::GetNumBitsForBuilder() const { return 1; } + +void ImmutableMapFieldGenerator::GenerateInterfaceMembers( + io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$int ${$get$capitalized_name$Count$}$();\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$boolean ${$contains$capitalized_name$$}$(\n" + " $key_type$ key);\n"); + printer->Annotate("{", "}", descriptor_); + if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { + printer->Print(variables_, + "/**\n" + " * Use {@link #get$capitalized_name$Map()} instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "java.util.Map<$boxed_key_type$, $value_enum_type$>\n" + "${$get$capitalized_name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$java.util.Map<$boxed_key_type$, $value_enum_type$>\n" + "${$get$capitalized_name$Map$}$();\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n" + " $key_type$ key,\n" + " $value_enum_type$ defaultValue);\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n" + " $key_type$ key);\n"); + printer->Annotate("{", "}", descriptor_); + if (SupportUnknownEnumValue(descriptor_->file())) { + printer->Print( + variables_, + "/**\n" + " * Use {@link #get$capitalized_name$ValueMap()} instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "java.util.Map<$type_parameters$>\n" + "${$get$capitalized_name$Value$}$();\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$java.util.Map<$type_parameters$>\n" + "${$get$capitalized_name$ValueMap$}$();\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$\n" + "$value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n" + " $key_type$ key,\n" + " $value_type$ defaultValue);\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$\n" + "$value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n" + " $key_type$ key);\n"); + printer->Annotate("{", "}", descriptor_); + } + } else { + printer->Print(variables_, + "/**\n" + " * Use {@link #get$capitalized_name$Map()} instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "java.util.Map<$type_parameters$>\n" + "${$get$capitalized_name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$java.util.Map<$type_parameters$>\n" + "${$get$capitalized_name$Map$}$();\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$\n" + "$value_type$ ${$get$capitalized_name$OrDefault$}$(\n" + " $key_type$ key,\n" + " $value_type$ defaultValue);\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$\n" + "$value_type$ ${$get$capitalized_name$OrThrow$}$(\n" + " $key_type$ key);\n"); + printer->Annotate("{", "}", descriptor_); + } +} + +void ImmutableMapFieldGenerator::GenerateMembers(io::Printer* printer) const { + printer->Print( + variables_, + "private static final class $capitalized_name$DefaultEntryHolder {\n" + " static final com.google.protobuf.MapEntry<\n" + " $type_parameters$> defaultEntry =\n" + " com.google.protobuf.MapEntry\n" + " .<$type_parameters$>newDefaultInstance(\n" + " $descriptor$\n" + " $key_wire_type$,\n" + " $key_default_value$,\n" + " $value_wire_type$,\n" + " $value_default_value$);\n" + "}\n"); + printer->Print(variables_, + "private com.google.protobuf.MapField<\n" + " $type_parameters$> $name$_;\n" + "private com.google.protobuf.MapField<$type_parameters$>\n" + "internalGet$capitalized_name$() {\n" + " if ($name$_ == null) {\n" + " return com.google.protobuf.MapField.emptyMapField(\n" + " $map_field_parameter$);\n" + " }\n" + " return $name$_;\n" + "}\n"); + if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { + printer->Print( + variables_, + "private static final\n" + "com.google.protobuf.Internal.MapAdapter.Converter<\n" + " java.lang.Integer, $value_enum_type$> $name$ValueConverter =\n" + " com.google.protobuf.Internal.MapAdapter.newEnumConverter(\n" + " $value_enum_type$.internalGetValueMap(),\n" + " $unrecognized_value$);\n"); + printer->Print( + variables_, + "private static final java.util.Map<$boxed_key_type$, " + "$value_enum_type$>\n" + "internalGetAdapted$capitalized_name$Map(\n" + " java.util.Map<$boxed_key_type$, $boxed_value_type$> map) {\n" + " return new com.google.protobuf.Internal.MapAdapter<\n" + " $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n" + " map, $name$ValueConverter);\n" + "}\n"); + } + GenerateMapGetters(printer); +} + +void ImmutableMapFieldGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + printer->Print(variables_, + "private com.google.protobuf.MapField<\n" + " $type_parameters$> $name$_;\n" + "private com.google.protobuf.MapField<$type_parameters$>\n" + "internalGet$capitalized_name$() {\n" + " if ($name$_ == null) {\n" + " return com.google.protobuf.MapField.emptyMapField(\n" + " $map_field_parameter$);\n" + " }\n" + " return $name$_;\n" + "}\n" + "private com.google.protobuf.MapField<$type_parameters$>\n" + "internalGetMutable$capitalized_name$() {\n" + " $on_changed$;\n" + " if ($name$_ == null) {\n" + " $name$_ = com.google.protobuf.MapField.newMapField(\n" + " $map_field_parameter$);\n" + " }\n" + " if (!$name$_.isMutable()) {\n" + " $name$_ = $name$_.copy();\n" + " }\n" + " return $name$_;\n" + "}\n"); + GenerateMapGetters(printer); + printer->Print(variables_, + "$deprecation$\n" + "public Builder ${$clear$capitalized_name$$}$() {\n" + " internalGetMutable$capitalized_name$().getMutableMap()\n" + " .clear();\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$\n" + "public Builder ${$remove$capitalized_name$$}$(\n" + " $key_type$ key) {\n" + " $key_null_check$\n" + " internalGetMutable$capitalized_name$().getMutableMap()\n" + " .remove(key);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { + printer->Print( + variables_, + "/**\n" + " * Use alternate mutation accessors instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" + "${$getMutable$capitalized_name$$}$() {\n" + " return internalGetAdapted$capitalized_name$Map(\n" + " internalGetMutable$capitalized_name$().getMutableMap());\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder ${$put$capitalized_name$$}$(\n" + " $key_type$ key,\n" + " $value_enum_type$ value) {\n" + " $key_null_check$\n" + " $value_null_check$\n" + " internalGetMutable$capitalized_name$().getMutableMap()\n" + " .put(key, $name$ValueConverter.doBackward(value));\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$public Builder ${$putAll$capitalized_name$$}$(\n" + " java.util.Map<$boxed_key_type$, $value_enum_type$> values) {\n" + " internalGetAdapted$capitalized_name$Map(\n" + " internalGetMutable$capitalized_name$().getMutableMap())\n" + " .putAll(values);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + if (SupportUnknownEnumValue(descriptor_->file())) { + printer->Print( + variables_, + "/**\n" + " * Use alternate mutation accessors instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" + "${$getMutable$capitalized_name$Value$}$() {\n" + " return internalGetMutable$capitalized_name$().getMutableMap();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$public Builder ${$put$capitalized_name$Value$}$(\n" + " $key_type$ key,\n" + " $value_type$ value) {\n" + " $key_null_check$\n" + " $value_null_check$\n" + " internalGetMutable$capitalized_name$().getMutableMap()\n" + " .put(key, value);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$public Builder ${$putAll$capitalized_name$Value$}$(\n" + " java.util.Map<$boxed_key_type$, $boxed_value_type$> values) {\n" + " internalGetMutable$capitalized_name$().getMutableMap()\n" + " .putAll(values);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } + } else { + printer->Print( + variables_, + "/**\n" + " * Use alternate mutation accessors instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "public java.util.Map<$type_parameters$>\n" + "${$getMutable$capitalized_name$$}$() {\n" + " return internalGetMutable$capitalized_name$().getMutableMap();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$" + "public Builder ${$put$capitalized_name$$}$(\n" + " $key_type$ key,\n" + " $value_type$ value) {\n" + " $key_null_check$\n" + " $value_null_check$\n" + " internalGetMutable$capitalized_name$().getMutableMap()\n" + " .put(key, value);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$\n" + "public Builder ${$putAll$capitalized_name$$}$(\n" + " java.util.Map<$type_parameters$> values) {\n" + " internalGetMutable$capitalized_name$().getMutableMap()\n" + " .putAll(values);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } +} + +void ImmutableMapFieldGenerator::GenerateMapGetters( + io::Printer* printer) const { + printer->Print(variables_, + "$deprecation$\n" + "public int ${$get$capitalized_name$Count$}$() {\n" + " return internalGet$capitalized_name$().getMap().size();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$\n" + "@java.lang.Override\n" + "public boolean ${$contains$capitalized_name$$}$(\n" + " $key_type$ key) {\n" + " $key_null_check$\n" + " return internalGet$capitalized_name$().getMap().containsKey(key);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { + printer->Print(variables_, + "/**\n" + " * Use {@link #get$capitalized_name$Map()} instead.\n" + " */\n" + "@java.lang.Override\n" + "@java.lang.Deprecated\n" + "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" + "${$get$capitalized_name$$}$() {\n" + " return get$capitalized_name$Map();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$\n" + "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" + "${$get$capitalized_name$Map$}$() {\n" + " return internalGetAdapted$capitalized_name$Map(\n" + " internalGet$capitalized_name$().getMap());" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$\n" + "public $value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n" + " $key_type$ key,\n" + " $value_enum_type$ defaultValue) {\n" + " $key_null_check$\n" + " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" + " internalGet$capitalized_name$().getMap();\n" + " return map.containsKey(key)\n" + " ? $name$ValueConverter.doForward(map.get(key))\n" + " : defaultValue;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$\n" + "public $value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n" + " $key_type$ key) {\n" + " $key_null_check$\n" + " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" + " internalGet$capitalized_name$().getMap();\n" + " if (!map.containsKey(key)) {\n" + " throw new java.lang.IllegalArgumentException();\n" + " }\n" + " return $name$ValueConverter.doForward(map.get(key));\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + if (SupportUnknownEnumValue(descriptor_->file())) { + printer->Print( + variables_, + "/**\n" + " * Use {@link #get$capitalized_name$ValueMap()} instead.\n" + " */\n" + "@java.lang.Override\n" + "@java.lang.Deprecated\n" + "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" + "${$get$capitalized_name$Value$}$() {\n" + " return get$capitalized_name$ValueMap();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$\n" + "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" + "${$get$capitalized_name$ValueMap$}$() {\n" + " return internalGet$capitalized_name$().getMap();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$\n" + "public $value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n" + " $key_type$ key,\n" + " $value_type$ defaultValue) {\n" + " $key_null_check$\n" + " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" + " internalGet$capitalized_name$().getMap();\n" + " return map.containsKey(key) ? map.get(key) : defaultValue;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$\n" + "public $value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n" + " $key_type$ key) {\n" + " $key_null_check$\n" + " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" + " internalGet$capitalized_name$().getMap();\n" + " if (!map.containsKey(key)) {\n" + " throw new java.lang.IllegalArgumentException();\n" + " }\n" + " return map.get(key);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } + } else { + printer->Print(variables_, + "/**\n" + " * Use {@link #get$capitalized_name$Map()} instead.\n" + " */\n" + "@java.lang.Override\n" + "@java.lang.Deprecated\n" + "public java.util.Map<$type_parameters$> " + "${$get$capitalized_name$$}$() {\n" + " return get$capitalized_name$Map();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$\n" + "public java.util.Map<$type_parameters$> " + "${$get$capitalized_name$Map$}$() {\n" + " return internalGet$capitalized_name$().getMap();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$\n" + "public $value_type$ ${$get$capitalized_name$OrDefault$}$(\n" + " $key_type$ key,\n" + " $value_type$ defaultValue) {\n" + " $key_null_check$\n" + " java.util.Map<$type_parameters$> map =\n" + " internalGet$capitalized_name$().getMap();\n" + " return map.containsKey(key) ? map.get(key) : defaultValue;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$\n" + "public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n" + " $key_type$ key) {\n" + " $key_null_check$\n" + " java.util.Map<$type_parameters$> map =\n" + " internalGet$capitalized_name$().getMap();\n" + " if (!map.containsKey(key)) {\n" + " throw new java.lang.IllegalArgumentException();\n" + " }\n" + " return map.get(key);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } +} + +void ImmutableMapFieldGenerator::GenerateKotlinDslMembers( + io::Printer* printer) const { + printer->Print( + variables_, + "/**\n" + " * An uninstantiable, behaviorless type to represent the field in\n" + " * generics.\n" + " */\n" + "@kotlin.OptIn" + "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n" + "public class ${$$kt_capitalized_name$Proxy$}$ private constructor()" + " : com.google.protobuf.kotlin.DslProxy()\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$kt_deprecation$ public val $kt_name$: " + "com.google.protobuf.kotlin.DslMap" + "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n" + " @kotlin.jvm.JvmSynthetic\n" + " @JvmName(\"get$kt_capitalized_name$Map\")\n" + " get() = com.google.protobuf.kotlin.DslMap(\n" + " $kt_dsl_builder$.${$get$capitalized_name$Map$}$()\n" + " )\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@JvmName(\"put$kt_capitalized_name$\")\n" + "public fun com.google.protobuf.kotlin.DslMap" + "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n" + " .put(key: $kt_key_type$, value: $kt_value_type$) {\n" + " $kt_dsl_builder$.${$put$capitalized_name$$}$(key, value)\n" + " }\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@JvmName(\"set$kt_capitalized_name$\")\n" + "@Suppress(\"NOTHING_TO_INLINE\")\n" + "public inline operator fun com.google.protobuf.kotlin.DslMap" + "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n" + " .set(key: $kt_key_type$, value: $kt_value_type$) {\n" + " put(key, value)\n" + " }\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@JvmName(\"remove$kt_capitalized_name$\")\n" + "public fun com.google.protobuf.kotlin.DslMap" + "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n" + " .remove(key: $kt_key_type$) {\n" + " $kt_dsl_builder$.${$remove$capitalized_name$$}$(key)\n" + " }\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@JvmName(\"putAll$kt_capitalized_name$\")\n" + "public fun com.google.protobuf.kotlin.DslMap" + "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n" + " .putAll(map: kotlin.collections.Map<$kt_key_type$, $kt_value_type$>) " + "{\n" + " $kt_dsl_builder$.${$putAll$capitalized_name$$}$(map)\n" + " }\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@JvmName(\"clear$kt_capitalized_name$\")\n" + "public fun com.google.protobuf.kotlin.DslMap" + "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n" + " .clear() {\n" + " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n" + " }\n"); +} + +void ImmutableMapFieldGenerator::GenerateFieldBuilderInitializationCode( + io::Printer* printer) const { + // Nothing to initialize. +} + +void ImmutableMapFieldGenerator::GenerateInitializationCode( + io::Printer* printer) const { + // Nothing to initialize. +} + +void ImmutableMapFieldGenerator::GenerateBuilderClearCode( + io::Printer* printer) const { + printer->Print(variables_, + "internalGetMutable$capitalized_name$().clear();\n"); +} + +void ImmutableMapFieldGenerator::GenerateMergingCode( + io::Printer* printer) const { + printer->Print(variables_, + "internalGetMutable$capitalized_name$().mergeFrom(\n" + " other.internalGet$capitalized_name$());\n"); +} + +void ImmutableMapFieldGenerator::GenerateBuildingCode( + io::Printer* printer) const { + printer->Print(variables_, + "result.$name$_ = internalGet$capitalized_name$();\n" + "result.$name$_.makeImmutable();\n"); +} + +void ImmutableMapFieldGenerator::GenerateParsingCode( + io::Printer* printer) const { + printer->Print(variables_, + "if (!$get_mutable_bit_parser$) {\n" + " $name$_ = com.google.protobuf.MapField.newMapField(\n" + " $map_field_parameter$);\n" + " $set_mutable_bit_parser$;\n" + "}\n"); + if (!SupportUnknownEnumValue(descriptor_->file()) && + GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { + printer->Print( + variables_, + "com.google.protobuf.ByteString bytes = input.readBytes();\n" + "com.google.protobuf.MapEntry<$type_parameters$>\n" + "$name$__ = $default_entry$.getParserForType().parseFrom(bytes);\n"); + printer->Print( + variables_, + "if ($value_enum_type$.forNumber($name$__.getValue()) == null) {\n" + " unknownFields.mergeLengthDelimitedField($number$, bytes);\n" + "} else {\n" + " $name$_.getMutableMap().put(\n" + " $name$__.getKey(), $name$__.getValue());\n" + "}\n"); + } else { + printer->Print( + variables_, + "com.google.protobuf.MapEntry<$type_parameters$>\n" + "$name$__ = input.readMessage(\n" + " $default_entry$.getParserForType(), extensionRegistry);\n" + "$name$_.getMutableMap().put(\n" + " $name$__.getKey(), $name$__.getValue());\n"); + } +} + +void ImmutableMapFieldGenerator::GenerateParsingDoneCode( + io::Printer* printer) const { + // Nothing to do here. +} + +void ImmutableMapFieldGenerator::GenerateSerializationCode( + io::Printer* printer) const { + printer->Print(variables_, + "com.google.protobuf.GeneratedMessage$ver$\n" + " .serialize$short_key_type$MapTo(\n" + " output,\n" + " internalGet$capitalized_name$(),\n" + " $default_entry$,\n" + " $number$);\n"); +} + +void ImmutableMapFieldGenerator::GenerateSerializedSizeCode( + io::Printer* printer) const { + printer->Print( + variables_, + "for (java.util.Map.Entry<$type_parameters$> entry\n" + " : internalGet$capitalized_name$().getMap().entrySet()) {\n" + " com.google.protobuf.MapEntry<$type_parameters$>\n" + " $name$__ = $default_entry$.newBuilderForType()\n" + " .setKey(entry.getKey())\n" + " .setValue(entry.getValue())\n" + " .build();\n" + " size += com.google.protobuf.CodedOutputStream\n" + " .computeMessageSize($number$, $name$__);\n" + "}\n"); +} + +void ImmutableMapFieldGenerator::GenerateEqualsCode( + io::Printer* printer) const { + printer->Print(variables_, + "if (!internalGet$capitalized_name$().equals(\n" + " other.internalGet$capitalized_name$())) return false;\n"); +} + +void ImmutableMapFieldGenerator::GenerateHashCode(io::Printer* printer) const { + printer->Print( + variables_, + "if (!internalGet$capitalized_name$().getMap().isEmpty()) {\n" + " hash = (37 * hash) + $constant_name$;\n" + " hash = (53 * hash) + internalGet$capitalized_name$().hashCode();\n" + "}\n"); +} + +std::string ImmutableMapFieldGenerator::GetBoxedType() const { + return name_resolver_->GetImmutableClassName(descriptor_->message_type()); +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_map_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_map_field.h new file mode 100644 index 00000000..e309391f --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_map_field.h @@ -0,0 +1,82 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_MAP_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_MAP_FIELD_H__ + +#include <compiler/java/java_field.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +class ImmutableMapFieldGenerator : public ImmutableFieldGenerator { + public: + explicit ImmutableMapFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, int builderBitIndex, + Context* context); + ~ImmutableMapFieldGenerator() override; + + // implements ImmutableFieldGenerator --------------------------------------- + int GetNumBitsForMessage() const override; + int GetNumBitsForBuilder() const override; + void GenerateInterfaceMembers(io::Printer* printer) const override; + void GenerateMembers(io::Printer* printer) const override; + void GenerateBuilderMembers(io::Printer* printer) const override; + void GenerateInitializationCode(io::Printer* printer) const override; + void GenerateBuilderClearCode(io::Printer* printer) const override; + void GenerateMergingCode(io::Printer* printer) const override; + void GenerateBuildingCode(io::Printer* printer) const override; + void GenerateParsingCode(io::Printer* printer) const override; + void GenerateParsingDoneCode(io::Printer* printer) const override; + void GenerateSerializationCode(io::Printer* printer) const override; + void GenerateSerializedSizeCode(io::Printer* printer) const override; + void GenerateFieldBuilderInitializationCode( + io::Printer* printer) const override; + void GenerateEqualsCode(io::Printer* printer) const override; + void GenerateHashCode(io::Printer* printer) const override; + void GenerateKotlinDslMembers(io::Printer* printer) const override; + + std::string GetBoxedType() const override; + + private: + const FieldDescriptor* descriptor_; + std::map<std::string, std::string> variables_; + ClassNameResolver* name_resolver_; + void GenerateMapGetters(io::Printer* printer) const; +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_MAP_FIELD_H__ diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_map_field_lite.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_map_field_lite.cc new file mode 100644 index 00000000..b210bc45 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_map_field_lite.cc @@ -0,0 +1,909 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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. + +#include <compiler/java/java_map_field_lite.h> + +#include <cstdint> + +#include <compiler/java/java_context.h> +#include <compiler/java/java_doc_comment.h> +#include <compiler/java/java_helpers.h> +#include <compiler/java/java_name_resolver.h> +#include <io/printer.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +namespace { + +const FieldDescriptor* KeyField(const FieldDescriptor* descriptor) { + GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, descriptor->type()); + const Descriptor* message = descriptor->message_type(); + GOOGLE_CHECK(message->options().map_entry()); + return message->FindFieldByName("key"); +} + +const FieldDescriptor* ValueField(const FieldDescriptor* descriptor) { + GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, descriptor->type()); + const Descriptor* message = descriptor->message_type(); + GOOGLE_CHECK(message->options().map_entry()); + return message->FindFieldByName("value"); +} + +std::string TypeName(const FieldDescriptor* field, + ClassNameResolver* name_resolver, bool boxed) { + if (GetJavaType(field) == JAVATYPE_MESSAGE) { + return name_resolver->GetImmutableClassName(field->message_type()); + } else if (GetJavaType(field) == JAVATYPE_ENUM) { + return name_resolver->GetImmutableClassName(field->enum_type()); + } else { + return boxed ? BoxedPrimitiveTypeName(GetJavaType(field)) + : PrimitiveTypeName(GetJavaType(field)); + } +} + +std::string KotlinTypeName(const FieldDescriptor* field, + ClassNameResolver* name_resolver) { + if (GetJavaType(field) == JAVATYPE_MESSAGE) { + return name_resolver->GetImmutableClassName(field->message_type()); + } else if (GetJavaType(field) == JAVATYPE_ENUM) { + return name_resolver->GetImmutableClassName(field->enum_type()); + } else { + return KotlinTypeName(GetJavaType(field)); + } +} + +std::string WireType(const FieldDescriptor* field) { + return "com.google.protobuf.WireFormat.FieldType." + + std::string(FieldTypeName(field->type())); +} + +void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, + int builderBitIndex, const FieldGeneratorInfo* info, + Context* context, + std::map<std::string, std::string>* variables) { + SetCommonFieldVariables(descriptor, info, variables); + + ClassNameResolver* name_resolver = context->GetNameResolver(); + (*variables)["type"] = + name_resolver->GetImmutableClassName(descriptor->message_type()); + const FieldDescriptor* key = KeyField(descriptor); + const FieldDescriptor* value = ValueField(descriptor); + const JavaType keyJavaType = GetJavaType(key); + const JavaType valueJavaType = GetJavaType(value); + + (*variables)["key_type"] = TypeName(key, name_resolver, false); + (*variables)["boxed_key_type"] = TypeName(key, name_resolver, true); + (*variables)["kt_key_type"] = KotlinTypeName(key, name_resolver); + (*variables)["kt_value_type"] = KotlinTypeName(value, name_resolver); + (*variables)["key_wire_type"] = WireType(key); + (*variables)["key_default_value"] = DefaultValue(key, true, name_resolver); + // We use `x.getClass()` as a null check because it generates less bytecode + // than an `if (x == null) { throw ... }` statement. + (*variables)["key_null_check"] = + IsReferenceType(keyJavaType) + ? "java.lang.Class<?> keyClass = key.getClass();" + : ""; + (*variables)["value_null_check"] = + IsReferenceType(valueJavaType) + ? "java.lang.Class<?> valueClass = value.getClass();" + : ""; + + if (GetJavaType(value) == JAVATYPE_ENUM) { + // We store enums as Integers internally. + (*variables)["value_type"] = "int"; + (*variables)["boxed_value_type"] = "java.lang.Integer"; + (*variables)["value_wire_type"] = WireType(value); + (*variables)["value_default_value"] = + DefaultValue(value, true, name_resolver) + ".getNumber()"; + + (*variables)["value_enum_type"] = TypeName(value, name_resolver, false); + + if (SupportUnknownEnumValue(descriptor->file())) { + // Map unknown values to a special UNRECOGNIZED value if supported. + (*variables)["unrecognized_value"] = + (*variables)["value_enum_type"] + ".UNRECOGNIZED"; + } else { + // Map unknown values to the default value if we don't have UNRECOGNIZED. + (*variables)["unrecognized_value"] = + DefaultValue(value, true, name_resolver); + } + } else { + (*variables)["value_type"] = TypeName(value, name_resolver, false); + (*variables)["boxed_value_type"] = TypeName(value, name_resolver, true); + (*variables)["value_wire_type"] = WireType(value); + (*variables)["value_default_value"] = + DefaultValue(value, true, name_resolver); + } + (*variables)["type_parameters"] = + (*variables)["boxed_key_type"] + ", " + (*variables)["boxed_value_type"]; + // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported + // by the proto compiler + (*variables)["deprecation"] = + descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; + (*variables)["kt_deprecation"] = + descriptor->options().deprecated() + ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] + + " is deprecated\") " + : ""; + + (*variables)["default_entry"] = + (*variables)["capitalized_name"] + "DefaultEntryHolder.defaultEntry"; +} + +} // namespace + +ImmutableMapFieldLiteGenerator::ImmutableMapFieldLiteGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, Context* context) + : descriptor_(descriptor), + context_(context), + name_resolver_(context->GetNameResolver()) { + SetMessageVariables(descriptor, messageBitIndex, 0, + context->GetFieldGeneratorInfo(descriptor), context, + &variables_); +} + +ImmutableMapFieldLiteGenerator::~ImmutableMapFieldLiteGenerator() {} + +int ImmutableMapFieldLiteGenerator::GetNumBitsForMessage() const { return 0; } + +void ImmutableMapFieldLiteGenerator::GenerateInterfaceMembers( + io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$int ${$get$capitalized_name$Count$}$();\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$boolean ${$contains$capitalized_name$$}$(\n" + " $key_type$ key);\n"); + printer->Annotate("{", "}", descriptor_); + if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { + printer->Print(variables_, + "/**\n" + " * Use {@link #get$capitalized_name$Map()} instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "java.util.Map<$boxed_key_type$, $value_enum_type$>\n" + "${$get$capitalized_name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$java.util.Map<$boxed_key_type$, $value_enum_type$>\n" + "${$get$capitalized_name$Map$}$();\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n" + " $key_type$ key,\n" + " $value_enum_type$ defaultValue);\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n" + " $key_type$ key);\n"); + printer->Annotate("{", "}", descriptor_); + if (SupportUnknownEnumValue(descriptor_->file())) { + printer->Print( + variables_, + "/**\n" + " * Use {@link #get$capitalized_name$ValueMap()} instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "java.util.Map<$type_parameters$>\n" + "${$get$capitalized_name$Value$}$();\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$java.util.Map<$type_parameters$>\n" + "${$get$capitalized_name$ValueMap$}$();\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$\n" + "$value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n" + " $key_type$ key,\n" + " $value_type$ defaultValue);\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$\n" + "$value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n" + " $key_type$ key);\n"); + printer->Annotate("{", "}", descriptor_); + } + } else { + printer->Print(variables_, + "/**\n" + " * Use {@link #get$capitalized_name$Map()} instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "java.util.Map<$type_parameters$>\n" + "${$get$capitalized_name$$}$();\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$java.util.Map<$type_parameters$>\n" + "${$get$capitalized_name$Map$}$();\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$\n" + "$value_type$ ${$get$capitalized_name$OrDefault$}$(\n" + " $key_type$ key,\n" + " $value_type$ defaultValue);\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$\n" + "$value_type$ ${$get$capitalized_name$OrThrow$}$(\n" + " $key_type$ key);\n"); + printer->Annotate("{", "}", descriptor_); + } +} + +void ImmutableMapFieldLiteGenerator::GenerateMembers( + io::Printer* printer) const { + printer->Print( + variables_, + "private static final class $capitalized_name$DefaultEntryHolder {\n" + " static final com.google.protobuf.MapEntryLite<\n" + " $type_parameters$> defaultEntry =\n" + " com.google.protobuf.MapEntryLite\n" + " .<$type_parameters$>newDefaultInstance(\n" + " $key_wire_type$,\n" + " $key_default_value$,\n" + " $value_wire_type$,\n" + " $value_default_value$);\n" + "}\n"); + printer->Print(variables_, + "private com.google.protobuf.MapFieldLite<\n" + " $type_parameters$> $name$_ =\n" + " com.google.protobuf.MapFieldLite.emptyMapField();\n" + "private com.google.protobuf.MapFieldLite<$type_parameters$>\n" + "internalGet$capitalized_name$() {\n" + " return $name$_;\n" + "}\n" + "private com.google.protobuf.MapFieldLite<$type_parameters$>\n" + "internalGetMutable$capitalized_name$() {\n" + " if (!$name$_.isMutable()) {\n" + " $name$_ = $name$_.mutableCopy();\n" + " }\n" + " return $name$_;\n" + "}\n"); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$\n" + "public int ${$get$capitalized_name$Count$}$() {\n" + " return internalGet$capitalized_name$().size();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$\n" + "public boolean ${$contains$capitalized_name$$}$(\n" + " $key_type$ key) {\n" + " $key_null_check$\n" + " return internalGet$capitalized_name$().containsKey(key);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { + printer->Print( + variables_, + "private static final\n" + "com.google.protobuf.Internal.MapAdapter.Converter<\n" + " java.lang.Integer, $value_enum_type$> $name$ValueConverter =\n" + " com.google.protobuf.Internal.MapAdapter.newEnumConverter(\n" + " $value_enum_type$.internalGetValueMap(),\n" + " $unrecognized_value$);\n"); + printer->Print(variables_, + "/**\n" + " * Use {@link #get$capitalized_name$Map()} instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" + "${$get$capitalized_name$$}$() {\n" + " return get$capitalized_name$Map();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$\n" + "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" + "${$get$capitalized_name$Map$}$() {\n" + " return java.util.Collections.unmodifiableMap(\n" + " new com.google.protobuf.Internal.MapAdapter<\n" + " $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n" + " internalGet$capitalized_name$(),\n" + " $name$ValueConverter));\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$\n" + "public $value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n" + " $key_type$ key,\n" + " $value_enum_type$ defaultValue) {\n" + " $key_null_check$\n" + " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" + " internalGet$capitalized_name$();\n" + " return map.containsKey(key)\n" + " ? $name$ValueConverter.doForward(map.get(key))\n" + " : defaultValue;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$\n" + "public $value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n" + " $key_type$ key) {\n" + " $key_null_check$\n" + " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" + " internalGet$capitalized_name$();\n" + " if (!map.containsKey(key)) {\n" + " throw new java.lang.IllegalArgumentException();\n" + " }\n" + " return $name$ValueConverter.doForward(map.get(key));\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + if (SupportUnknownEnumValue(descriptor_->file())) { + printer->Print( + variables_, + "/**\n" + " * Use {@link #get$capitalized_name$ValueMap()} instead.\n" + " */\n" + "@java.lang.Override\n" + "@java.lang.Deprecated\n" + "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" + "${$get$capitalized_name$Value$}$() {\n" + " return get$capitalized_name$ValueMap();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$\n" + "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" + "${$get$capitalized_name$ValueMap$}$() {\n" + " return java.util.Collections.unmodifiableMap(\n" + " internalGet$capitalized_name$());\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$\n" + "public $value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n" + " $key_type$ key,\n" + " $value_type$ defaultValue) {\n" + " $key_null_check$\n" + " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" + " internalGet$capitalized_name$();\n" + " return map.containsKey(key) ? map.get(key) : defaultValue;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$\n" + "public $value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n" + " $key_type$ key) {\n" + " $key_null_check$\n" + " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" + " internalGet$capitalized_name$();\n" + " if (!map.containsKey(key)) {\n" + " throw new java.lang.IllegalArgumentException();\n" + " }\n" + " return map.get(key);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } + } else { + printer->Print(variables_, + "/**\n" + " * Use {@link #get$capitalized_name$Map()} instead.\n" + " */\n" + "@java.lang.Override\n" + "@java.lang.Deprecated\n" + "public java.util.Map<$type_parameters$> " + "${$get$capitalized_name$$}$() {\n" + " return get$capitalized_name$Map();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$\n" + "public java.util.Map<$type_parameters$> " + "${$get$capitalized_name$Map$}$() {\n" + " return java.util.Collections.unmodifiableMap(\n" + " internalGet$capitalized_name$());\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$\n" + "public $value_type$ ${$get$capitalized_name$OrDefault$}$(\n" + " $key_type$ key,\n" + " $value_type$ defaultValue) {\n" + " $key_null_check$\n" + " java.util.Map<$type_parameters$> map =\n" + " internalGet$capitalized_name$();\n" + " return map.containsKey(key) ? map.get(key) : defaultValue;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$\n" + "public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n" + " $key_type$ key) {\n" + " $key_null_check$\n" + " java.util.Map<$type_parameters$> map =\n" + " internalGet$capitalized_name$();\n" + " if (!map.containsKey(key)) {\n" + " throw new java.lang.IllegalArgumentException();\n" + " }\n" + " return map.get(key);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } + + // Generate private setters for the builder to proxy into. + if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "private java.util.Map<$boxed_key_type$, $value_enum_type$>\n" + "getMutable$capitalized_name$Map() {\n" + " return new com.google.protobuf.Internal.MapAdapter<\n" + " $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n" + " internalGetMutable$capitalized_name$(),\n" + " $name$ValueConverter);\n" + "}\n"); + if (SupportUnknownEnumValue(descriptor_->file())) { + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "private java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" + "getMutable$capitalized_name$ValueMap() {\n" + " return internalGetMutable$capitalized_name$();\n" + "}\n"); + } + } else { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private java.util.Map<$type_parameters$>\n" + "getMutable$capitalized_name$Map() {\n" + " return internalGetMutable$capitalized_name$();\n" + "}\n"); + } +} + +void ImmutableMapFieldLiteGenerator::GenerateFieldInfo( + io::Printer* printer, std::vector<uint16_t>* output) const { + WriteIntToUtf16CharSequence(descriptor_->number(), output); + WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_), + output); + printer->Print(variables_, + "\"$name$_\",\n" + "$default_entry$,\n"); + if (!SupportUnknownEnumValue(descriptor_) && + GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { + PrintEnumVerifierLogic(printer, ValueField(descriptor_), variables_, + /*var_name=*/"$value_enum_type$", + /*terminating_string=*/",\n", + /*enforce_lite=*/context_->EnforceLite()); + } +} + +void ImmutableMapFieldLiteGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$\n" + "public int ${$get$capitalized_name$Count$}$() {\n" + " return instance.get$capitalized_name$Map().size();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$\n" + "public boolean ${$contains$capitalized_name$$}$(\n" + " $key_type$ key) {\n" + " $key_null_check$\n" + " return instance.get$capitalized_name$Map().containsKey(key);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + printer->Print(variables_, + "$deprecation$\n" + "public Builder ${$clear$capitalized_name$$}$() {\n" + " copyOnWrite();\n" + " instance.getMutable$capitalized_name$Map().clear();\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$\n" + "public Builder ${$remove$capitalized_name$$}$(\n" + " $key_type$ key) {\n" + " $key_null_check$\n" + " copyOnWrite();\n" + " instance.getMutable$capitalized_name$Map().remove(key);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) { + printer->Print(variables_, + "/**\n" + " * Use {@link #get$capitalized_name$Map()} instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" + "${$get$capitalized_name$$}$() {\n" + " return get$capitalized_name$Map();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$\n" + "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n" + "${$get$capitalized_name$Map$}$() {\n" + " return java.util.Collections.unmodifiableMap(\n" + " instance.get$capitalized_name$Map());\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$\n" + "public $value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n" + " $key_type$ key,\n" + " $value_enum_type$ defaultValue) {\n" + " $key_null_check$\n" + " java.util.Map<$boxed_key_type$, $value_enum_type$> map =\n" + " instance.get$capitalized_name$Map();\n" + " return map.containsKey(key)\n" + " ? map.get(key)\n" + " : defaultValue;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$\n" + "public $value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n" + " $key_type$ key) {\n" + " $key_null_check$\n" + " java.util.Map<$boxed_key_type$, $value_enum_type$> map =\n" + " instance.get$capitalized_name$Map();\n" + " if (!map.containsKey(key)) {\n" + " throw new java.lang.IllegalArgumentException();\n" + " }\n" + " return map.get(key);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$public Builder ${$put$capitalized_name$$}$(\n" + " $key_type$ key,\n" + " $value_enum_type$ value) {\n" + " $key_null_check$\n" + " $value_null_check$\n" + " copyOnWrite();\n" + " instance.getMutable$capitalized_name$Map().put(key, value);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$public Builder ${$putAll$capitalized_name$$}$(\n" + " java.util.Map<$boxed_key_type$, $value_enum_type$> values) {\n" + " copyOnWrite();\n" + " instance.getMutable$capitalized_name$Map().putAll(values);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + if (SupportUnknownEnumValue(descriptor_->file())) { + printer->Print( + variables_, + "/**\n" + " * Use {@link #get$capitalized_name$ValueMap()} instead.\n" + " */\n" + "@java.lang.Override\n" + "@java.lang.Deprecated\n" + "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" + "${$get$capitalized_name$Value$}$() {\n" + " return get$capitalized_name$ValueMap();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$\n" + "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n" + "${$get$capitalized_name$ValueMap$}$() {\n" + " return java.util.Collections.unmodifiableMap(\n" + " instance.get$capitalized_name$ValueMap());\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$\n" + "public $value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n" + " $key_type$ key,\n" + " $value_type$ defaultValue) {\n" + " $key_null_check$\n" + " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" + " instance.get$capitalized_name$ValueMap();\n" + " return map.containsKey(key) ? map.get(key) : defaultValue;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$\n" + "public $value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n" + " $key_type$ key) {\n" + " $key_null_check$\n" + " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n" + " instance.get$capitalized_name$ValueMap();\n" + " if (!map.containsKey(key)) {\n" + " throw new java.lang.IllegalArgumentException();\n" + " }\n" + " return map.get(key);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$public Builder ${$put$capitalized_name$Value$}$(\n" + " $key_type$ key,\n" + " $value_type$ value) {\n" + " $key_null_check$\n" + " copyOnWrite();\n" + " instance.getMutable$capitalized_name$ValueMap().put(key, value);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$public Builder ${$putAll$capitalized_name$Value$}$(\n" + " java.util.Map<$boxed_key_type$, $boxed_value_type$> values) {\n" + " copyOnWrite();\n" + " instance.getMutable$capitalized_name$ValueMap().putAll(values);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } + } else { + printer->Print(variables_, + "/**\n" + " * Use {@link #get$capitalized_name$Map()} instead.\n" + " */\n" + "@java.lang.Override\n" + "@java.lang.Deprecated\n" + "public java.util.Map<$type_parameters$> " + "${$get$capitalized_name$$}$() {\n" + " return get$capitalized_name$Map();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$" + "public java.util.Map<$type_parameters$> " + "${$get$capitalized_name$Map$}$() {\n" + " return java.util.Collections.unmodifiableMap(\n" + " instance.get$capitalized_name$Map());\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$\n" + "public $value_type$ ${$get$capitalized_name$OrDefault$}$(\n" + " $key_type$ key,\n" + " $value_type$ defaultValue) {\n" + " $key_null_check$\n" + " java.util.Map<$type_parameters$> map =\n" + " instance.get$capitalized_name$Map();\n" + " return map.containsKey(key) ? map.get(key) : defaultValue;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$\n" + "public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n" + " $key_type$ key) {\n" + " $key_null_check$\n" + " java.util.Map<$type_parameters$> map =\n" + " instance.get$capitalized_name$Map();\n" + " if (!map.containsKey(key)) {\n" + " throw new java.lang.IllegalArgumentException();\n" + " }\n" + " return map.get(key);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$" + "public Builder ${$put$capitalized_name$$}$(\n" + " $key_type$ key,\n" + " $value_type$ value) {\n" + " $key_null_check$\n" + " $value_null_check$\n" + " copyOnWrite();\n" + " instance.getMutable$capitalized_name$Map().put(key, value);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$" + "public Builder ${$putAll$capitalized_name$$}$(\n" + " java.util.Map<$type_parameters$> values) {\n" + " copyOnWrite();\n" + " instance.getMutable$capitalized_name$Map().putAll(values);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } +} + +void ImmutableMapFieldLiteGenerator::GenerateKotlinDslMembers( + io::Printer* printer) const { + printer->Print( + variables_, + "/**\n" + " * An uninstantiable, behaviorless type to represent the field in\n" + " * generics.\n" + " */\n" + "@kotlin.OptIn" + "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n" + "public class ${$$kt_capitalized_name$Proxy$}$ private constructor()" + " : com.google.protobuf.kotlin.DslProxy()\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$kt_deprecation$ public val $kt_name$: " + "com.google.protobuf.kotlin.DslMap" + "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n" + " @kotlin.jvm.JvmSynthetic\n" + " @JvmName(\"get$kt_capitalized_name$Map\")\n" + " get() = com.google.protobuf.kotlin.DslMap(\n" + " $kt_dsl_builder$.${$get$capitalized_name$Map$}$()\n" + " )\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@JvmName(\"put$kt_capitalized_name$\")\n" + "public fun com.google.protobuf.kotlin.DslMap" + "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n" + " .put(key: $kt_key_type$, value: $kt_value_type$) {\n" + " $kt_dsl_builder$.${$put$capitalized_name$$}$(key, value)\n" + " }\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@JvmName(\"set$kt_capitalized_name$\")\n" + "@Suppress(\"NOTHING_TO_INLINE\")\n" + "public inline operator fun com.google.protobuf.kotlin.DslMap" + "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n" + " .set(key: $kt_key_type$, value: $kt_value_type$) {\n" + " put(key, value)\n" + " }\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@JvmName(\"remove$kt_capitalized_name$\")\n" + "public fun com.google.protobuf.kotlin.DslMap" + "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n" + " .remove(key: $kt_key_type$) {\n" + " $kt_dsl_builder$.${$remove$capitalized_name$$}$(key)\n" + " }\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@JvmName(\"putAll$kt_capitalized_name$\")\n" + "public fun com.google.protobuf.kotlin.DslMap" + "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n" + " .putAll(map: kotlin.collections.Map<$kt_key_type$, $kt_value_type$>) " + "{\n" + " $kt_dsl_builder$.${$putAll$capitalized_name$$}$(map)\n" + " }\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@JvmName(\"clear$kt_capitalized_name$\")\n" + "public fun com.google.protobuf.kotlin.DslMap" + "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n" + " .clear() {\n" + " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n" + " }\n"); +} + +void ImmutableMapFieldLiteGenerator::GenerateInitializationCode( + io::Printer* printer) const { + // Nothing to initialize. +} + +std::string ImmutableMapFieldLiteGenerator::GetBoxedType() const { + return name_resolver_->GetImmutableClassName(descriptor_->message_type()); +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_map_field_lite.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_map_field_lite.h new file mode 100644 index 00000000..7017982d --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_map_field_lite.h @@ -0,0 +1,74 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_MAP_FIELD_LITE_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_MAP_FIELD_LITE_H__ + +#include <cstdint> + +#include <compiler/java/java_field.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +class ImmutableMapFieldLiteGenerator : public ImmutableFieldLiteGenerator { + public: + explicit ImmutableMapFieldLiteGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + Context* context); + ~ImmutableMapFieldLiteGenerator() override; + + // implements ImmutableFieldLiteGenerator ------------------------------------ + int GetNumBitsForMessage() const override; + void GenerateInterfaceMembers(io::Printer* printer) const override; + void GenerateMembers(io::Printer* printer) const override; + void GenerateBuilderMembers(io::Printer* printer) const override; + void GenerateInitializationCode(io::Printer* printer) const override; + void GenerateFieldInfo(io::Printer* printer, + std::vector<uint16_t>* output) const override; + void GenerateKotlinDslMembers(io::Printer* printer) const override; + + std::string GetBoxedType() const override; + + private: + const FieldDescriptor* descriptor_; + std::map<std::string, std::string> variables_; + Context* context_; + ClassNameResolver* name_resolver_; +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_MAP_FIELD_LITE_H__ diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message.cc new file mode 100644 index 00000000..38edc769 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message.cc @@ -0,0 +1,1729 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <compiler/java/java_message.h> + +#include <algorithm> +#include <cstdint> +#include <map> +#include <memory> +#include <vector> + +#include <compiler/java/java_context.h> +#include <compiler/java/java_doc_comment.h> +#include <compiler/java/java_enum.h> +#include <compiler/java/java_extension.h> +#include <compiler/java/java_generator_factory.h> +#include <compiler/java/java_helpers.h> +#include <compiler/java/java_message_builder.h> +#include <compiler/java/java_message_builder_lite.h> +#include <compiler/java/java_name_resolver.h> +#include <descriptor.pb.h> +#include <io/coded_stream.h> +#include <io/printer.h> +#include <wire_format.h> +#include <stubs/strutil.h> +#include <stubs/substitute.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +using internal::WireFormat; +using internal::WireFormatLite; + +namespace { +std::string MapValueImmutableClassdName(const Descriptor* descriptor, + ClassNameResolver* name_resolver) { + const FieldDescriptor* value_field = descriptor->FindFieldByName("value"); + GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, value_field->type()); + return name_resolver->GetImmutableClassName(value_field->message_type()); +} +} // namespace + +// =================================================================== + +MessageGenerator::MessageGenerator(const Descriptor* descriptor) + : descriptor_(descriptor) { + for (int i = 0; i < descriptor_->field_count(); i++) { + if (IsRealOneof(descriptor_->field(i))) { + oneofs_.insert(descriptor_->field(i)->containing_oneof()); + } + } +} + +MessageGenerator::~MessageGenerator() {} + +// =================================================================== +ImmutableMessageGenerator::ImmutableMessageGenerator( + const Descriptor* descriptor, Context* context) + : MessageGenerator(descriptor), + context_(context), + name_resolver_(context->GetNameResolver()), + field_generators_(descriptor, context_) { + GOOGLE_CHECK(HasDescriptorMethods(descriptor->file(), context->EnforceLite())) + << "Generator factory error: A non-lite message generator is used to " + "generate lite messages."; +} + +ImmutableMessageGenerator::~ImmutableMessageGenerator() {} + +void ImmutableMessageGenerator::GenerateStaticVariables( + io::Printer* printer, int* bytecode_estimate) { + // Because descriptor.proto (com.google.protobuf.DescriptorProtos) is + // used in the construction of descriptors, we have a tricky bootstrapping + // problem. To help control static initialization order, we make sure all + // descriptors and other static data that depends on them are members of + // the outermost class in the file. This way, they will be initialized in + // a deterministic order. + + std::map<std::string, std::string> vars; + vars["identifier"] = UniqueFileScopeIdentifier(descriptor_); + vars["index"] = StrCat(descriptor_->index()); + vars["classname"] = name_resolver_->GetImmutableClassName(descriptor_); + if (descriptor_->containing_type() != NULL) { + vars["parent"] = UniqueFileScopeIdentifier(descriptor_->containing_type()); + } + if (MultipleJavaFiles(descriptor_->file(), /* immutable = */ true)) { + // We can only make these package-private since the classes that use them + // are in separate files. + vars["private"] = ""; + } else { + vars["private"] = "private "; + } + if (*bytecode_estimate <= kMaxStaticSize) { + vars["final"] = "final "; + } else { + vars["final"] = ""; + } + + // The descriptor for this type. + printer->Print( + vars, + // TODO(teboring): final needs to be added back. The way to fix it is to + // generate methods that can construct the types, and then still declare + // the types, and then init them in clinit with the new method calls. + "$private$static $final$com.google.protobuf.Descriptors.Descriptor\n" + " internal_$identifier$_descriptor;\n"); + *bytecode_estimate += 30; + + // And the FieldAccessorTable. + GenerateFieldAccessorTable(printer, bytecode_estimate); + + // Generate static members for all nested types. + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + // TODO(kenton): Reuse MessageGenerator objects? + ImmutableMessageGenerator(descriptor_->nested_type(i), context_) + .GenerateStaticVariables(printer, bytecode_estimate); + } +} + +int ImmutableMessageGenerator::GenerateStaticVariableInitializers( + io::Printer* printer) { + int bytecode_estimate = 0; + std::map<std::string, std::string> vars; + vars["identifier"] = UniqueFileScopeIdentifier(descriptor_); + vars["index"] = StrCat(descriptor_->index()); + vars["classname"] = name_resolver_->GetImmutableClassName(descriptor_); + if (descriptor_->containing_type() != NULL) { + vars["parent"] = UniqueFileScopeIdentifier(descriptor_->containing_type()); + } + + // The descriptor for this type. + if (descriptor_->containing_type() == NULL) { + printer->Print(vars, + "internal_$identifier$_descriptor =\n" + " getDescriptor().getMessageTypes().get($index$);\n"); + bytecode_estimate += 30; + } else { + printer->Print( + vars, + "internal_$identifier$_descriptor =\n" + " internal_$parent$_descriptor.getNestedTypes().get($index$);\n"); + bytecode_estimate += 30; + } + + // And the FieldAccessorTable. + bytecode_estimate += GenerateFieldAccessorTableInitializer(printer); + + // Generate static member initializers for all nested types. + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + // TODO(kenton): Reuse MessageGenerator objects? + bytecode_estimate += + ImmutableMessageGenerator(descriptor_->nested_type(i), context_) + .GenerateStaticVariableInitializers(printer); + } + return bytecode_estimate; +} + +void ImmutableMessageGenerator::GenerateFieldAccessorTable( + io::Printer* printer, int* bytecode_estimate) { + std::map<std::string, std::string> vars; + vars["identifier"] = UniqueFileScopeIdentifier(descriptor_); + if (MultipleJavaFiles(descriptor_->file(), /* immutable = */ true)) { + // We can only make these package-private since the classes that use them + // are in separate files. + vars["private"] = ""; + } else { + vars["private"] = "private "; + } + if (*bytecode_estimate <= kMaxStaticSize) { + vars["final"] = "final "; + } else { + vars["final"] = ""; + } + vars["ver"] = GeneratedCodeVersionSuffix(); + printer->Print( + vars, + "$private$static $final$\n" + " com.google.protobuf.GeneratedMessage$ver$.FieldAccessorTable\n" + " internal_$identifier$_fieldAccessorTable;\n"); + + // The following bytecode_estimate calculation logic must stay in sync with + // the similar logic in the GenerateFieldAccessorTableInitializer method below + // to make sure that the generated static final fields are initialized in the + // static initialization block directly. + // + // 6 bytes per field and oneof + *bytecode_estimate += + 10 + 6 * descriptor_->field_count() + 6 * descriptor_->oneof_decl_count(); +} + +int ImmutableMessageGenerator::GenerateFieldAccessorTableInitializer( + io::Printer* printer) { + int bytecode_estimate = 10; + printer->Print( + "internal_$identifier$_fieldAccessorTable = new\n" + " com.google.protobuf.GeneratedMessage$ver$.FieldAccessorTable(\n" + " internal_$identifier$_descriptor,\n" + " new java.lang.String[] { ", + "identifier", UniqueFileScopeIdentifier(descriptor_), "ver", + GeneratedCodeVersionSuffix()); + // All the bytecode_estimate calculation logic in this method must stay in + // sync with the similar logic in the GenerateFieldAccessorTable method + // above. See the corresponding comment in GenerateFieldAccessorTable for + // details. + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field); + bytecode_estimate += 6; + printer->Print("\"$field_name$\", ", "field_name", info->capitalized_name); + } + // We reproduce synthetic oneofs here since proto reflection needs these. + for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { + const OneofDescriptor* oneof = descriptor_->oneof_decl(i); + const OneofGeneratorInfo* info = context_->GetOneofGeneratorInfo(oneof); + bytecode_estimate += 6; + printer->Print("\"$oneof_name$\", ", "oneof_name", info->capitalized_name); + } + printer->Print("});\n"); + return bytecode_estimate; +} + +// =================================================================== + +void ImmutableMessageGenerator::GenerateInterface(io::Printer* printer) { + MaybePrintGeneratedAnnotation(context_, printer, descriptor_, + /* immutable = */ true, "OrBuilder"); + if (descriptor_->extension_range_count() > 0) { + printer->Print( + "$deprecation$public interface ${$$classname$OrBuilder$}$ extends\n" + " $extra_interfaces$\n" + " com.google.protobuf.GeneratedMessage$ver$.\n" + " ExtendableMessageOrBuilder<$classname$> {\n", + "deprecation", + descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "", + "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), + "classname", descriptor_->name(), "{", "", "}", "", "ver", + GeneratedCodeVersionSuffix()); + } else { + printer->Print( + "$deprecation$public interface ${$$classname$OrBuilder$}$ extends\n" + " $extra_interfaces$\n" + " com.google.protobuf.MessageOrBuilder {\n", + "deprecation", + descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "", + "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), + "classname", descriptor_->name(), "{", "", "}", ""); + } + printer->Annotate("{", "}", descriptor_); + + printer->Indent(); + for (int i = 0; i < descriptor_->field_count(); i++) { + printer->Print("\n"); + field_generators_.get(descriptor_->field(i)) + .GenerateInterfaceMembers(printer); + } + for (auto oneof : oneofs_) { + printer->Print( + "\n" + "public $classname$.$oneof_capitalized_name$Case " + "get$oneof_capitalized_name$Case();\n", + "oneof_capitalized_name", + context_->GetOneofGeneratorInfo(oneof)->capitalized_name, "classname", + context_->GetNameResolver()->GetImmutableClassName(descriptor_)); + } + printer->Outdent(); + + printer->Print("}\n"); +} + +// =================================================================== + +void ImmutableMessageGenerator::Generate(io::Printer* printer) { + bool is_own_file = IsOwnFile(descriptor_, /* immutable = */ true); + + std::map<std::string, std::string> variables; + variables["static"] = is_own_file ? "" : "static "; + variables["classname"] = descriptor_->name(); + variables["extra_interfaces"] = ExtraMessageInterfaces(descriptor_); + variables["ver"] = GeneratedCodeVersionSuffix(); + variables["deprecation"] = + descriptor_->options().deprecated() ? "@java.lang.Deprecated " : ""; + + WriteMessageDocComment(printer, descriptor_); + MaybePrintGeneratedAnnotation(context_, printer, descriptor_, + /* immutable = */ true); + // The builder_type stores the super type name of the nested Builder class. + std::string builder_type; + if (descriptor_->extension_range_count() > 0) { + printer->Print( + variables, + "$deprecation$public $static$final class $classname$ extends\n"); + printer->Annotate("classname", descriptor_); + printer->Print( + variables, + " com.google.protobuf.GeneratedMessage$ver$.ExtendableMessage<\n" + " $classname$> implements\n" + " $extra_interfaces$\n" + " $classname$OrBuilder {\n"); + builder_type = strings::Substitute( + "com.google.protobuf.GeneratedMessage$1.ExtendableBuilder<$0, ?>", + name_resolver_->GetImmutableClassName(descriptor_), + GeneratedCodeVersionSuffix()); + } else { + printer->Print( + variables, + "$deprecation$public $static$final class $classname$ extends\n"); + printer->Annotate("classname", descriptor_); + printer->Print(variables, + " com.google.protobuf.GeneratedMessage$ver$ implements\n" + " $extra_interfaces$\n" + " $classname$OrBuilder {\n"); + builder_type = + strings::Substitute("com.google.protobuf.GeneratedMessage$0.Builder<?>", + GeneratedCodeVersionSuffix()); + } + printer->Print("private static final long serialVersionUID = 0L;\n"); + + printer->Indent(); + // Using builder_type, instead of Builder, prevents the Builder class from + // being loaded into PermGen space when the default instance is created. + // This optimizes the PermGen space usage for clients that do not modify + // messages. + printer->Print( + "// Use $classname$.newBuilder() to construct.\n" + "private $classname$($buildertype$ builder) {\n" + " super(builder);\n" + "}\n", + "classname", descriptor_->name(), "buildertype", builder_type); + printer->Print("private $classname$() {\n", "classname", descriptor_->name()); + printer->Indent(); + GenerateInitializers(printer); + printer->Outdent(); + printer->Print( + "}\n" + "\n"); + + printer->Print(variables, + "@java.lang.Override\n" + "@SuppressWarnings({\"unused\"})\n" + "protected java.lang.Object newInstance(\n" + " UnusedPrivateParameter unused) {\n" + " return new $classname$();\n" + "}\n" + "\n"); + + printer->Print( + "@java.lang.Override\n" + "public final com.google.protobuf.UnknownFieldSet\n" + "getUnknownFields() {\n" + " return this.unknownFields;\n" + "}\n"); + + if (context_->HasGeneratedMethods(descriptor_)) { + GenerateParsingConstructor(printer); + } + + GenerateDescriptorMethods(printer); + + // Nested types + for (int i = 0; i < descriptor_->enum_type_count(); i++) { + EnumGenerator(descriptor_->enum_type(i), true, context_).Generate(printer); + } + + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + // Don't generate Java classes for map entry messages. + if (IsMapEntry(descriptor_->nested_type(i))) continue; + ImmutableMessageGenerator messageGenerator(descriptor_->nested_type(i), + context_); + messageGenerator.GenerateInterface(printer); + messageGenerator.Generate(printer); + } + + // Integers for bit fields. + int totalBits = 0; + for (int i = 0; i < descriptor_->field_count(); i++) { + totalBits += + field_generators_.get(descriptor_->field(i)).GetNumBitsForMessage(); + } + int totalInts = (totalBits + 31) / 32; + for (int i = 0; i < totalInts; i++) { + printer->Print("private int $bit_field_name$;\n", "bit_field_name", + GetBitFieldName(i)); + } + + // oneof + std::map<std::string, std::string> vars; + for (auto oneof : oneofs_) { + vars["oneof_name"] = context_->GetOneofGeneratorInfo(oneof)->name; + vars["oneof_capitalized_name"] = + context_->GetOneofGeneratorInfo(oneof)->capitalized_name; + vars["oneof_index"] = StrCat((oneof)->index()); + // oneofCase_ and oneof_ + printer->Print(vars, + "private int $oneof_name$Case_ = 0;\n" + "private java.lang.Object $oneof_name$_;\n"); + // OneofCase enum + printer->Print( + vars, + "public enum $oneof_capitalized_name$Case\n" + // TODO(dweis): Remove EnumLite when we want to break compatibility with + // 3.x users + " implements com.google.protobuf.Internal.EnumLite,\n" + " com.google.protobuf.AbstractMessage.InternalOneOfEnum {\n"); + printer->Indent(); + for (int j = 0; j < (oneof)->field_count(); j++) { + const FieldDescriptor* field = (oneof)->field(j); + printer->Print( + "$deprecation$$field_name$($field_number$),\n", "deprecation", + field->options().deprecated() ? "@java.lang.Deprecated " : "", + "field_name", ToUpper(field->name()), "field_number", + StrCat(field->number())); + } + printer->Print("$cap_oneof_name$_NOT_SET(0);\n", "cap_oneof_name", + ToUpper(vars["oneof_name"])); + printer->Print(vars, + "private final int value;\n" + "private $oneof_capitalized_name$Case(int value) {\n" + " this.value = value;\n" + "}\n"); + printer->Print( + vars, + "/**\n" + " * @param value The number of the enum to look for.\n" + " * @return The enum associated with the given number.\n" + " * @deprecated Use {@link #forNumber(int)} instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "public static $oneof_capitalized_name$Case valueOf(int value) {\n" + " return forNumber(value);\n" + "}\n" + "\n" + "public static $oneof_capitalized_name$Case forNumber(int value) {\n" + " switch (value) {\n"); + for (int j = 0; j < (oneof)->field_count(); j++) { + const FieldDescriptor* field = (oneof)->field(j); + printer->Print(" case $field_number$: return $field_name$;\n", + "field_number", StrCat(field->number()), + "field_name", ToUpper(field->name())); + } + printer->Print( + " case 0: return $cap_oneof_name$_NOT_SET;\n" + " default: return null;\n" + " }\n" + "}\n" + "public int getNumber() {\n" + " return this.value;\n" + "}\n", + "cap_oneof_name", ToUpper(vars["oneof_name"])); + printer->Outdent(); + printer->Print("};\n\n"); + // oneofCase() + printer->Print(vars, + "public $oneof_capitalized_name$Case\n" + "get$oneof_capitalized_name$Case() {\n" + " return $oneof_capitalized_name$Case.forNumber(\n" + " $oneof_name$Case_);\n" + "}\n" + "\n"); + } + + if (IsAnyMessage(descriptor_)) { + GenerateAnyMethods(printer); + } + + // Fields + for (int i = 0; i < descriptor_->field_count(); i++) { + printer->Print("public static final int $constant_name$ = $number$;\n", + "constant_name", FieldConstantName(descriptor_->field(i)), + "number", StrCat(descriptor_->field(i)->number())); + printer->Annotate("constant_name", descriptor_->field(i)); + field_generators_.get(descriptor_->field(i)).GenerateMembers(printer); + printer->Print("\n"); + } + + if (context_->HasGeneratedMethods(descriptor_)) { + GenerateIsInitialized(printer); + GenerateMessageSerializationMethods(printer); + GenerateEqualsAndHashCode(printer); + } + + + GenerateParseFromMethods(printer); + GenerateBuilder(printer); + + printer->Print( + "\n" + "// @@protoc_insertion_point(class_scope:$full_name$)\n", + "full_name", descriptor_->full_name()); + + // Carefully initialize the default instance in such a way that it doesn't + // conflict with other initialization. + printer->Print("private static final $classname$ DEFAULT_INSTANCE;\n", + "classname", + name_resolver_->GetImmutableClassName(descriptor_)); + printer->Print( + "static {\n" + " DEFAULT_INSTANCE = new $classname$();\n" + "}\n" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + + printer->Print( + "public static $classname$ getDefaultInstance() {\n" + " return DEFAULT_INSTANCE;\n" + "}\n" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + + // 'of' method for Wrappers + if (IsWrappersProtoFile(descriptor_->file())) { + printer->Print( + "public static $classname$ of($field_type$ value) {\n" + " return newBuilder().setValue(value).build();\n" + "}\n" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_), + "field_type", PrimitiveTypeName(GetJavaType(descriptor_->field(0)))); + } + + GenerateParser(printer); + + printer->Print( + "@java.lang.Override\n" + "public $classname$ getDefaultInstanceForType() {\n" + " return DEFAULT_INSTANCE;\n" + "}\n" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + + // Extensions must be declared after the DEFAULT_INSTANCE is initialized + // because the DEFAULT_INSTANCE is used by the extension to lazily retrieve + // the outer class's FileDescriptor. + for (int i = 0; i < descriptor_->extension_count(); i++) { + ImmutableExtensionGenerator(descriptor_->extension(i), context_) + .Generate(printer); + } + + printer->Outdent(); + printer->Print("}\n\n"); +} + +// =================================================================== + +void ImmutableMessageGenerator::GenerateMessageSerializationMethods( + io::Printer* printer) { + std::unique_ptr<const FieldDescriptor*[]> sorted_fields( + SortFieldsByNumber(descriptor_)); + + std::vector<const Descriptor::ExtensionRange*> sorted_extensions; + sorted_extensions.reserve(descriptor_->extension_range_count()); + for (int i = 0; i < descriptor_->extension_range_count(); ++i) { + sorted_extensions.push_back(descriptor_->extension_range(i)); + } + std::sort(sorted_extensions.begin(), sorted_extensions.end(), + ExtensionRangeOrdering()); + printer->Print( + "@java.lang.Override\n" + "public void writeTo(com.google.protobuf.CodedOutputStream output)\n" + " throws java.io.IOException {\n"); + printer->Indent(); + + if (HasPackedFields(descriptor_)) { + // writeTo(CodedOutputStream output) might be invoked without + // getSerializedSize() ever being called, but we need the memoized + // sizes in case this message has packed fields. Rather than emit checks + // for each packed field, just call getSerializedSize() up front. In most + // cases, getSerializedSize() will have already been called anyway by one + // of the wrapper writeTo() methods, making this call cheap. + printer->Print("getSerializedSize();\n"); + } + + if (descriptor_->extension_range_count() > 0) { + if (descriptor_->options().message_set_wire_format()) { + printer->Print( + "com.google.protobuf.GeneratedMessage$ver$\n" + " .ExtendableMessage<$classname$>.ExtensionWriter\n" + " extensionWriter = newMessageSetExtensionWriter();\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_), + "ver", GeneratedCodeVersionSuffix()); + } else { + printer->Print( + "com.google.protobuf.GeneratedMessage$ver$\n" + " .ExtendableMessage<$classname$>.ExtensionWriter\n" + " extensionWriter = newExtensionWriter();\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_), + "ver", GeneratedCodeVersionSuffix()); + } + } + + // Merge the fields and the extension ranges, both sorted by field number. + for (int i = 0, j = 0; + i < descriptor_->field_count() || j < sorted_extensions.size();) { + if (i == descriptor_->field_count()) { + GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]); + } else if (j == sorted_extensions.size()) { + GenerateSerializeOneField(printer, sorted_fields[i++]); + } else if (sorted_fields[i]->number() < sorted_extensions[j]->start) { + GenerateSerializeOneField(printer, sorted_fields[i++]); + } else { + GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]); + } + } + + if (descriptor_->options().message_set_wire_format()) { + printer->Print("unknownFields.writeAsMessageSetTo(output);\n"); + } else { + printer->Print("unknownFields.writeTo(output);\n"); + } + + printer->Outdent(); + printer->Print( + "}\n" + "\n" + "@java.lang.Override\n" + "public int getSerializedSize() {\n" + " int size = memoizedSize;\n" + " if (size != -1) return size;\n" + "\n"); + printer->Indent(); + + printer->Print("size = 0;\n"); + + for (int i = 0; i < descriptor_->field_count(); i++) { + field_generators_.get(sorted_fields[i]).GenerateSerializedSizeCode(printer); + } + + if (descriptor_->extension_range_count() > 0) { + if (descriptor_->options().message_set_wire_format()) { + printer->Print("size += extensionsSerializedSizeAsMessageSet();\n"); + } else { + printer->Print("size += extensionsSerializedSize();\n"); + } + } + + if (descriptor_->options().message_set_wire_format()) { + printer->Print("size += unknownFields.getSerializedSizeAsMessageSet();\n"); + } else { + printer->Print("size += unknownFields.getSerializedSize();\n"); + } + + printer->Print( + "memoizedSize = size;\n" + "return size;\n"); + + printer->Outdent(); + printer->Print( + "}\n" + "\n"); +} + +void ImmutableMessageGenerator::GenerateParseFromMethods(io::Printer* printer) { + // Note: These are separate from GenerateMessageSerializationMethods() + // because they need to be generated even for messages that are optimized + // for code size. + printer->Print( + "public static $classname$ parseFrom(\n" + " java.nio.ByteBuffer data)\n" + " throws com.google.protobuf.InvalidProtocolBufferException {\n" + " return PARSER.parseFrom(data);\n" + "}\n" + "public static $classname$ parseFrom(\n" + " java.nio.ByteBuffer data,\n" + " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" + " throws com.google.protobuf.InvalidProtocolBufferException {\n" + " return PARSER.parseFrom(data, extensionRegistry);\n" + "}\n" + "public static $classname$ parseFrom(\n" + " com.google.protobuf.ByteString data)\n" + " throws com.google.protobuf.InvalidProtocolBufferException {\n" + " return PARSER.parseFrom(data);\n" + "}\n" + "public static $classname$ parseFrom(\n" + " com.google.protobuf.ByteString data,\n" + " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" + " throws com.google.protobuf.InvalidProtocolBufferException {\n" + " return PARSER.parseFrom(data, extensionRegistry);\n" + "}\n" + "public static $classname$ parseFrom(byte[] data)\n" + " throws com.google.protobuf.InvalidProtocolBufferException {\n" + " return PARSER.parseFrom(data);\n" + "}\n" + "public static $classname$ parseFrom(\n" + " byte[] data,\n" + " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" + " throws com.google.protobuf.InvalidProtocolBufferException {\n" + " return PARSER.parseFrom(data, extensionRegistry);\n" + "}\n" + "public static $classname$ parseFrom(java.io.InputStream input)\n" + " throws java.io.IOException {\n" + " return com.google.protobuf.GeneratedMessage$ver$\n" + " .parseWithIOException(PARSER, input);\n" + "}\n" + "public static $classname$ parseFrom(\n" + " java.io.InputStream input,\n" + " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" + " throws java.io.IOException {\n" + " return com.google.protobuf.GeneratedMessage$ver$\n" + " .parseWithIOException(PARSER, input, extensionRegistry);\n" + "}\n" + "public static $classname$ parseDelimitedFrom(java.io.InputStream " + "input)\n" + " throws java.io.IOException {\n" + " return com.google.protobuf.GeneratedMessage$ver$\n" + " .parseDelimitedWithIOException(PARSER, input);\n" + "}\n" + "public static $classname$ parseDelimitedFrom(\n" + " java.io.InputStream input,\n" + " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" + " throws java.io.IOException {\n" + " return com.google.protobuf.GeneratedMessage$ver$\n" + " .parseDelimitedWithIOException(PARSER, input, " + "extensionRegistry);\n" + "}\n" + "public static $classname$ parseFrom(\n" + " com.google.protobuf.CodedInputStream input)\n" + " throws java.io.IOException {\n" + " return com.google.protobuf.GeneratedMessage$ver$\n" + " .parseWithIOException(PARSER, input);\n" + "}\n" + "public static $classname$ parseFrom(\n" + " com.google.protobuf.CodedInputStream input,\n" + " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" + " throws java.io.IOException {\n" + " return com.google.protobuf.GeneratedMessage$ver$\n" + " .parseWithIOException(PARSER, input, extensionRegistry);\n" + "}\n" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_), "ver", + GeneratedCodeVersionSuffix()); +} + +void ImmutableMessageGenerator::GenerateSerializeOneField( + io::Printer* printer, const FieldDescriptor* field) { + field_generators_.get(field).GenerateSerializationCode(printer); +} + +void ImmutableMessageGenerator::GenerateSerializeOneExtensionRange( + io::Printer* printer, const Descriptor::ExtensionRange* range) { + printer->Print("extensionWriter.writeUntil($end$, output);\n", "end", + StrCat(range->end)); +} + +// =================================================================== + +void ImmutableMessageGenerator::GenerateBuilder(io::Printer* printer) { + // LITE_RUNTIME implements this at the GeneratedMessageLite level. + printer->Print( + "@java.lang.Override\n" + "public Builder newBuilderForType() { return newBuilder(); }\n"); + + printer->Print( + "public static Builder newBuilder() {\n" + " return DEFAULT_INSTANCE.toBuilder();\n" + "}\n" + "public static Builder newBuilder($classname$ prototype) {\n" + " return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);\n" + "}\n" + "@java.lang.Override\n" + "public Builder toBuilder() {\n" + " return this == DEFAULT_INSTANCE\n" + " ? new Builder() : new Builder().mergeFrom(this);\n" + "}\n" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + + printer->Print( + "@java.lang.Override\n" + "protected Builder newBuilderForType(\n" + " com.google.protobuf.GeneratedMessage$ver$.BuilderParent parent) {\n" + " Builder builder = new Builder(parent);\n" + " return builder;\n" + "}\n", + "ver", GeneratedCodeVersionSuffix()); + + MessageBuilderGenerator builderGenerator(descriptor_, context_); + builderGenerator.Generate(printer); +} + +void ImmutableMessageGenerator::GenerateDescriptorMethods( + io::Printer* printer) { + if (!descriptor_->options().no_standard_descriptor_accessor()) { + printer->Print( + "public static final com.google.protobuf.Descriptors.Descriptor\n" + " getDescriptor() {\n" + " return $fileclass$.internal_$identifier$_descriptor;\n" + "}\n" + "\n", + "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()), + "identifier", UniqueFileScopeIdentifier(descriptor_)); + } + std::vector<const FieldDescriptor*> map_fields; + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + if (GetJavaType(field) == JAVATYPE_MESSAGE && + IsMapEntry(field->message_type())) { + map_fields.push_back(field); + } + } + if (!map_fields.empty()) { + printer->Print( + "@SuppressWarnings({\"rawtypes\"})\n" + "@java.lang.Override\n" + "protected com.google.protobuf.MapField internalGetMapField(\n" + " int number) {\n" + " switch (number) {\n"); + printer->Indent(); + printer->Indent(); + for (int i = 0; i < map_fields.size(); ++i) { + const FieldDescriptor* field = map_fields[i]; + const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field); + printer->Print( + "case $number$:\n" + " return internalGet$capitalized_name$();\n", + "number", StrCat(field->number()), "capitalized_name", + info->capitalized_name); + } + printer->Print( + "default:\n" + " throw new RuntimeException(\n" + " \"Invalid map field number: \" + number);\n"); + printer->Outdent(); + printer->Outdent(); + printer->Print( + " }\n" + "}\n"); + } + printer->Print( + "@java.lang.Override\n" + "protected com.google.protobuf.GeneratedMessage$ver$.FieldAccessorTable\n" + " internalGetFieldAccessorTable() {\n" + " return $fileclass$.internal_$identifier$_fieldAccessorTable\n" + " .ensureFieldAccessorsInitialized(\n" + " $classname$.class, $classname$.Builder.class);\n" + "}\n" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_), + "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()), + "identifier", UniqueFileScopeIdentifier(descriptor_), "ver", + GeneratedCodeVersionSuffix()); +} + +// =================================================================== + +void ImmutableMessageGenerator::GenerateIsInitialized(io::Printer* printer) { + // Memoizes whether the protocol buffer is fully initialized (has all + // required fields). -1 means not yet computed. 0 means false and 1 means + // true. + printer->Print("private byte memoizedIsInitialized = -1;\n"); + printer->Print( + "@java.lang.Override\n" + "public final boolean isInitialized() {\n"); + printer->Indent(); + + // Don't directly compare to -1 to avoid an Android x86 JIT bug. + printer->Print( + "byte isInitialized = memoizedIsInitialized;\n" + "if (isInitialized == 1) return true;\n" + "if (isInitialized == 0) return false;\n" + "\n"); + + // Check that all required fields in this message are set. + // TODO(kenton): We can optimize this when we switch to putting all the + // "has" fields into a single bitfield. + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field); + + if (field->is_required()) { + printer->Print( + "if (!has$name$()) {\n" + " memoizedIsInitialized = 0;\n" + " return false;\n" + "}\n", + "name", info->capitalized_name); + } + } + + // Now check that all embedded messages are initialized. + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field); + if (GetJavaType(field) == JAVATYPE_MESSAGE && + HasRequiredFields(field->message_type())) { + switch (field->label()) { + case FieldDescriptor::LABEL_REQUIRED: + printer->Print( + "if (!get$name$().isInitialized()) {\n" + " memoizedIsInitialized = 0;\n" + " return false;\n" + "}\n", + "type", + name_resolver_->GetImmutableClassName(field->message_type()), + "name", info->capitalized_name); + break; + case FieldDescriptor::LABEL_OPTIONAL: + printer->Print( + "if (has$name$()) {\n" + " if (!get$name$().isInitialized()) {\n" + " memoizedIsInitialized = 0;\n" + " return false;\n" + " }\n" + "}\n", + "name", info->capitalized_name); + break; + case FieldDescriptor::LABEL_REPEATED: + if (IsMapEntry(field->message_type())) { + printer->Print( + "for ($type$ item : get$name$Map().values()) {\n" + " if (!item.isInitialized()) {\n" + " memoizedIsInitialized = 0;\n" + " return false;\n" + " }\n" + "}\n", + "type", + MapValueImmutableClassdName(field->message_type(), + name_resolver_), + "name", info->capitalized_name); + } else { + printer->Print( + "for (int i = 0; i < get$name$Count(); i++) {\n" + " if (!get$name$(i).isInitialized()) {\n" + " memoizedIsInitialized = 0;\n" + " return false;\n" + " }\n" + "}\n", + "type", + name_resolver_->GetImmutableClassName(field->message_type()), + "name", info->capitalized_name); + } + break; + } + } + } + + if (descriptor_->extension_range_count() > 0) { + printer->Print( + "if (!extensionsAreInitialized()) {\n" + " memoizedIsInitialized = 0;\n" + " return false;\n" + "}\n"); + } + + printer->Outdent(); + + printer->Print(" memoizedIsInitialized = 1;\n"); + + printer->Print( + " return true;\n" + "}\n" + "\n"); +} + +// =================================================================== + +namespace { +bool CheckHasBitsForEqualsAndHashCode(const FieldDescriptor* field) { + if (field->is_repeated()) { + return false; + } + if (HasHasbit(field)) { + return true; + } + return GetJavaType(field) == JAVATYPE_MESSAGE && !IsRealOneof(field); +} +} // namespace + +void ImmutableMessageGenerator::GenerateEqualsAndHashCode( + io::Printer* printer) { + printer->Print( + "@java.lang.Override\n" + "public boolean equals("); + printer->Print("final java.lang.Object obj) {\n"); + printer->Indent(); + printer->Print( + "if (obj == this) {\n" + " return true;\n" + "}\n" + "if (!(obj instanceof $classname$)) {\n" + " return super.equals(obj);\n" + "}\n" + "$classname$ other = ($classname$) obj;\n" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + if (!IsRealOneof(field)) { + const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field); + bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field); + if (check_has_bits) { + printer->Print( + "if (has$name$() != other.has$name$()) return false;\n" + "if (has$name$()) {\n", + "name", info->capitalized_name); + printer->Indent(); + } + field_generators_.get(field).GenerateEqualsCode(printer); + if (check_has_bits) { + printer->Outdent(); + printer->Print("}\n"); + } + } + } + + // Compare oneofs. + for (auto oneof : oneofs_) { + printer->Print( + "if (!get$oneof_capitalized_name$Case().equals(" + "other.get$oneof_capitalized_name$Case())) return false;\n", + "oneof_capitalized_name", + context_->GetOneofGeneratorInfo(oneof)->capitalized_name); + printer->Print("switch ($oneof_name$Case_) {\n", "oneof_name", + context_->GetOneofGeneratorInfo(oneof)->name); + printer->Indent(); + for (int j = 0; j < (oneof)->field_count(); j++) { + const FieldDescriptor* field = (oneof)->field(j); + printer->Print("case $field_number$:\n", "field_number", + StrCat(field->number())); + printer->Indent(); + field_generators_.get(field).GenerateEqualsCode(printer); + printer->Print("break;\n"); + printer->Outdent(); + } + printer->Print( + "case 0:\n" + "default:\n"); + printer->Outdent(); + printer->Print("}\n"); + } + + // Always consider unknown fields for equality. This will sometimes return + // false for non-canonical ordering when running in LITE_RUNTIME but it's + // the best we can do. + printer->Print( + "if (!unknownFields.equals(other.unknownFields)) return false;\n"); + if (descriptor_->extension_range_count() > 0) { + printer->Print( + "if (!getExtensionFields().equals(other.getExtensionFields()))\n" + " return false;\n"); + } + printer->Print("return true;\n"); + printer->Outdent(); + printer->Print( + "}\n" + "\n"); + + printer->Print( + "@java.lang.Override\n" + "public int hashCode() {\n"); + printer->Indent(); + printer->Print("if (memoizedHashCode != 0) {\n"); + printer->Indent(); + printer->Print("return memoizedHashCode;\n"); + printer->Outdent(); + printer->Print( + "}\n" + "int hash = 41;\n"); + + // If we output a getDescriptor() method, use that as it is more efficient. + if (descriptor_->options().no_standard_descriptor_accessor()) { + printer->Print("hash = (19 * hash) + getDescriptorForType().hashCode();\n"); + } else { + printer->Print("hash = (19 * hash) + getDescriptor().hashCode();\n"); + } + + // hashCode non-oneofs. + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + if (!IsRealOneof(field)) { + const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field); + bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field); + if (check_has_bits) { + printer->Print("if (has$name$()) {\n", "name", info->capitalized_name); + printer->Indent(); + } + field_generators_.get(field).GenerateHashCode(printer); + if (check_has_bits) { + printer->Outdent(); + printer->Print("}\n"); + } + } + } + + // hashCode oneofs. + for (auto oneof : oneofs_) { + printer->Print("switch ($oneof_name$Case_) {\n", "oneof_name", + context_->GetOneofGeneratorInfo(oneof)->name); + printer->Indent(); + for (int j = 0; j < (oneof)->field_count(); j++) { + const FieldDescriptor* field = (oneof)->field(j); + printer->Print("case $field_number$:\n", "field_number", + StrCat(field->number())); + printer->Indent(); + field_generators_.get(field).GenerateHashCode(printer); + printer->Print("break;\n"); + printer->Outdent(); + } + printer->Print( + "case 0:\n" + "default:\n"); + printer->Outdent(); + printer->Print("}\n"); + } + + if (descriptor_->extension_range_count() > 0) { + printer->Print("hash = hashFields(hash, getExtensionFields());\n"); + } + + printer->Print("hash = (29 * hash) + unknownFields.hashCode();\n"); + printer->Print( + "memoizedHashCode = hash;\n" + "return hash;\n"); + printer->Outdent(); + printer->Print( + "}\n" + "\n"); +} + +// =================================================================== + +void ImmutableMessageGenerator::GenerateExtensionRegistrationCode( + io::Printer* printer) { + for (int i = 0; i < descriptor_->extension_count(); i++) { + ImmutableExtensionGenerator(descriptor_->extension(i), context_) + .GenerateRegistrationCode(printer); + } + + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + ImmutableMessageGenerator(descriptor_->nested_type(i), context_) + .GenerateExtensionRegistrationCode(printer); + } +} + +// =================================================================== +void ImmutableMessageGenerator::GenerateParsingConstructor( + io::Printer* printer) { + std::unique_ptr<const FieldDescriptor*[]> sorted_fields( + SortFieldsByNumber(descriptor_)); + + printer->Print( + "private $classname$(\n" + " com.google.protobuf.CodedInputStream input,\n" + " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" + " throws com.google.protobuf.InvalidProtocolBufferException {\n", + "classname", descriptor_->name()); + printer->Indent(); + + // Initialize all fields to default. + printer->Print( + "this();\n" + "if (extensionRegistry == null) {\n" + " throw new java.lang.NullPointerException();\n" + "}\n"); + + // Use builder bits to track mutable repeated fields. + int totalBuilderBits = 0; + for (int i = 0; i < descriptor_->field_count(); i++) { + const ImmutableFieldGenerator& field = + field_generators_.get(descriptor_->field(i)); + totalBuilderBits += field.GetNumBitsForBuilder(); + } + int totalBuilderInts = (totalBuilderBits + 31) / 32; + for (int i = 0; i < totalBuilderInts; i++) { + printer->Print("int mutable_$bit_field_name$ = 0;\n", "bit_field_name", + GetBitFieldName(i)); + } + + printer->Print( + "com.google.protobuf.UnknownFieldSet.Builder unknownFields =\n" + " com.google.protobuf.UnknownFieldSet.newBuilder();\n"); + + printer->Print("try {\n"); + printer->Indent(); + + printer->Print( + "boolean done = false;\n" + "while (!done) {\n"); + printer->Indent(); + + printer->Print( + "int tag = input.readTag();\n" + "switch (tag) {\n"); + printer->Indent(); + + printer->Print( + "case 0:\n" // zero signals EOF / limit reached + " done = true;\n" + " break;\n"); + + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = sorted_fields[i]; + uint32_t tag = WireFormatLite::MakeTag( + field->number(), WireFormat::WireTypeForFieldType(field->type())); + + printer->Print("case $tag$: {\n", "tag", + StrCat(static_cast<int32_t>(tag))); + printer->Indent(); + + field_generators_.get(field).GenerateParsingCode(printer); + + printer->Outdent(); + printer->Print( + " break;\n" + "}\n"); + + if (field->is_packable()) { + // To make packed = true wire compatible, we generate parsing code from a + // packed version of this field regardless of field->options().packed(). + uint32_t packed_tag = WireFormatLite::MakeTag( + field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED); + printer->Print("case $tag$: {\n", "tag", + StrCat(static_cast<int32_t>(packed_tag))); + printer->Indent(); + + field_generators_.get(field).GenerateParsingCodeFromPacked(printer); + + printer->Outdent(); + printer->Print( + " break;\n" + "}\n"); + } + } + + printer->Print( + "default: {\n" + " if (!parseUnknownField(\n" + " input, unknownFields, extensionRegistry, tag)) {\n" + " done = true;\n" // it's an endgroup tag + " }\n" + " break;\n" + "}\n"); + + printer->Outdent(); + printer->Outdent(); + printer->Print( + " }\n" // switch (tag) + "}\n"); // while (!done) + + printer->Outdent(); + printer->Print( + "} catch (com.google.protobuf.InvalidProtocolBufferException e) {\n" + " throw e.setUnfinishedMessage(this);\n" + "} catch (java.io.IOException e) {\n" + " throw new com.google.protobuf.InvalidProtocolBufferException(\n" + " e).setUnfinishedMessage(this);\n" + "} finally {\n"); + printer->Indent(); + + // Make repeated field list immutable. + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = sorted_fields[i]; + field_generators_.get(field).GenerateParsingDoneCode(printer); + } + + // Make unknown fields immutable. + printer->Print("this.unknownFields = unknownFields.build();\n"); + + // Make extensions immutable. + printer->Print("makeExtensionsImmutable();\n"); + + printer->Outdent(); + printer->Outdent(); + printer->Print( + " }\n" // finally + "}\n"); +} + +// =================================================================== +void ImmutableMessageGenerator::GenerateParser(io::Printer* printer) { + printer->Print( + "$visibility$ static final com.google.protobuf.Parser<$classname$>\n" + " PARSER = new com.google.protobuf.AbstractParser<$classname$>() {\n", + "visibility", + ExposePublicParser(descriptor_->file()) ? "@java.lang.Deprecated public" + : "private", + "classname", descriptor_->name()); + printer->Indent(); + printer->Print( + "@java.lang.Override\n" + "public $classname$ parsePartialFrom(\n" + " com.google.protobuf.CodedInputStream input,\n" + " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" + " throws com.google.protobuf.InvalidProtocolBufferException {\n", + "classname", descriptor_->name()); + if (context_->HasGeneratedMethods(descriptor_)) { + printer->Print(" return new $classname$(input, extensionRegistry);\n", + "classname", descriptor_->name()); + } else { + // When parsing constructor isn't generated, use builder to parse + // messages. Note, will fallback to use reflection based mergeFieldFrom() + // in AbstractMessage.Builder. + printer->Indent(); + printer->Print( + "Builder builder = newBuilder();\n" + "try {\n" + " builder.mergeFrom(input, extensionRegistry);\n" + "} catch (com.google.protobuf.InvalidProtocolBufferException e) {\n" + " throw e.setUnfinishedMessage(builder.buildPartial());\n" + "} catch (java.io.IOException e) {\n" + " throw new com.google.protobuf.InvalidProtocolBufferException(\n" + " e.getMessage()).setUnfinishedMessage(\n" + " builder.buildPartial());\n" + "}\n" + "return builder.buildPartial();\n"); + printer->Outdent(); + } + printer->Print("}\n"); + printer->Outdent(); + printer->Print( + "};\n" + "\n"); + + printer->Print( + "public static com.google.protobuf.Parser<$classname$> parser() {\n" + " return PARSER;\n" + "}\n" + "\n" + "@java.lang.Override\n" + "public com.google.protobuf.Parser<$classname$> getParserForType() {\n" + " return PARSER;\n" + "}\n" + "\n", + "classname", descriptor_->name()); +} + +// =================================================================== +void ImmutableMessageGenerator::GenerateInitializers(io::Printer* printer) { + for (int i = 0; i < descriptor_->field_count(); i++) { + if (!IsRealOneof(descriptor_->field(i))) { + field_generators_.get(descriptor_->field(i)) + .GenerateInitializationCode(printer); + } + } +} + +// =================================================================== +void ImmutableMessageGenerator::GenerateMutableCopy(io::Printer* printer) { + printer->Print( + "protected com.google.protobuf.MutableMessage\n" + " internalMutableDefault() {\n" + " return MutableDefaultLoader.get();\n" + "}\n" + "\n" + "private static final class MutableDefaultLoader {\n" + " private static final java.lang.Object defaultOrRuntimeException;\n" + " static {\n" + " java.lang.Object local;\n" + " try {\n" + " local = internalMutableDefault(\"$mutable_name$\");\n" + " } catch (java.lang.RuntimeException e) {\n" + " local = e;\n" + " }\n" + " defaultOrRuntimeException = local;\n" + " }\n" + "\n" + " private MutableDefaultLoader() {}\n" + "\n" + " public static com.google.protobuf.MutableMessage get() {\n" + " if (defaultOrRuntimeException\n" + " instanceof java.lang.RuntimeException) {\n" + " throw (java.lang.RuntimeException) defaultOrRuntimeException;\n" + " }\n" + " return\n" + " (com.google.protobuf.MutableMessage) " + "defaultOrRuntimeException;\n" + " }\n" + "}\n", + "mutable_name", name_resolver_->GetJavaMutableClassName(descriptor_)); +} + +void ImmutableMessageGenerator::GenerateKotlinDsl(io::Printer* printer) const { + printer->Print( + "@kotlin.OptIn" + "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n" + "@com.google.protobuf.kotlin.ProtoDslMarker\n"); + printer->Print( + "public class Dsl private constructor(\n" + " private val _builder: $message$.Builder\n" + ") {\n" + " public companion object {\n" + " @kotlin.jvm.JvmSynthetic\n" + " @kotlin.PublishedApi\n" + " internal fun _create(builder: $message$.Builder): Dsl = " + "Dsl(builder)\n" + " }\n" + "\n" + " @kotlin.jvm.JvmSynthetic\n" + " @kotlin.PublishedApi\n" + " internal fun _build(): $message$ = _builder.build()\n", + "message", name_resolver_->GetClassName(descriptor_, true)); + + printer->Indent(); + + for (int i = 0; i < descriptor_->field_count(); i++) { + printer->Print("\n"); + field_generators_.get(descriptor_->field(i)) + .GenerateKotlinDslMembers(printer); + } + + for (auto oneof : oneofs_) { + printer->Print( + "public val $oneof_name$Case: $message$.$oneof_capitalized_name$Case\n" + " @JvmName(\"get$oneof_capitalized_name$Case\")\n" + " get() = _builder.get$oneof_capitalized_name$Case()\n\n" + "public fun clear$oneof_capitalized_name$() {\n" + " _builder.clear$oneof_capitalized_name$()\n" + "}\n", + "oneof_name", context_->GetOneofGeneratorInfo(oneof)->name, + "oneof_capitalized_name", + context_->GetOneofGeneratorInfo(oneof)->capitalized_name, "message", + name_resolver_->GetClassName(descriptor_, true)); + } + + if (descriptor_->extension_range_count() > 0) { + GenerateKotlinExtensions(printer); + } + + printer->Outdent(); + printer->Print("}\n"); +} + +void ImmutableMessageGenerator::GenerateKotlinMembers( + io::Printer* printer) const { + printer->Print( + "@kotlin.jvm.JvmSynthetic\n" + "public inline fun $camelcase_name$(block: $message_kt$.Dsl.() -> " + "kotlin.Unit): " + "$message$ " + "=\n" + " $message_kt$.Dsl._create($message$.newBuilder()).apply { block() " + "}._build()\n", + "camelcase_name", name_resolver_->GetKotlinFactoryName(descriptor_), + "message_kt", name_resolver_->GetKotlinExtensionsClassName(descriptor_), + "message", name_resolver_->GetClassName(descriptor_, true)); + + printer->Print("public object $name$Kt {\n", "name", descriptor_->name()); + printer->Indent(); + GenerateKotlinDsl(printer); + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + if (IsMapEntry(descriptor_->nested_type(i))) continue; + ImmutableMessageGenerator(descriptor_->nested_type(i), context_) + .GenerateKotlinMembers(printer); + } + printer->Outdent(); + printer->Print("}\n"); +} + +void ImmutableMessageGenerator::GenerateTopLevelKotlinMembers( + io::Printer* printer) const { + printer->Print( + "@kotlin.jvm.JvmSynthetic\n" + "public inline fun $message$.copy(block: $message_kt$.Dsl.() -> " + "kotlin.Unit): " + "$message$ =\n" + " $message_kt$.Dsl._create(this.toBuilder()).apply { block() " + "}._build()\n", + "message", name_resolver_->GetClassName(descriptor_, true), "message_kt", + name_resolver_->GetKotlinExtensionsClassName(descriptor_)); + + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + if (IsMapEntry(descriptor_->nested_type(i))) continue; + ImmutableMessageGenerator(descriptor_->nested_type(i), context_) + .GenerateTopLevelKotlinMembers(printer); + } +} + +void ImmutableMessageGenerator::GenerateKotlinExtensions( + io::Printer* printer) const { + std::string message_name = name_resolver_->GetClassName(descriptor_, true); + + printer->Print( + "@Suppress(\"UNCHECKED_CAST\")\n" + "@kotlin.jvm.JvmSynthetic\n" + "public operator fun <T> get(extension: " + "com.google.protobuf.ExtensionLite<$message$, T>): T {\n" + " return if (extension.isRepeated) {\n" + " get(extension as com.google.protobuf.ExtensionLite<$message$, " + "List<*>>) as T\n" + " } else {\n" + " _builder.getExtension(extension)\n" + " }\n" + "}\n\n", + "message", message_name); + + printer->Print( + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.OptIn" + "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n" + "@kotlin.jvm.JvmName(\"-getRepeatedExtension\")\n" + "public operator fun <E> get(\n" + " extension: com.google.protobuf.ExtensionLite<$message$, List<E>>\n" + "): com.google.protobuf.kotlin.ExtensionList<E, $message$> {\n" + " return com.google.protobuf.kotlin.ExtensionList(extension, " + "_builder.getExtension(extension))\n" + "}\n\n", + "message", message_name); + + printer->Print( + "@kotlin.jvm.JvmSynthetic\n" + "public operator fun contains(extension: " + "com.google.protobuf.ExtensionLite<$message$, *>): " + "Boolean {\n" + " return _builder.hasExtension(extension)\n" + "}\n\n", + "message", message_name); + + printer->Print( + "@kotlin.jvm.JvmSynthetic\n" + "public fun clear(extension: " + "com.google.protobuf.ExtensionLite<$message$, *>) " + "{\n" + " _builder.clearExtension(extension)\n" + "}\n\n", + "message", message_name); + + printer->Print( + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.PublishedApi\n" + "internal fun <T> setExtension(extension: " + "com.google.protobuf.ExtensionLite<$message$, T>, " + "value: T) {\n" + " _builder.setExtension(extension, value)\n" + "}\n\n", + "message", message_name); + + printer->Print( + "@kotlin.jvm.JvmSynthetic\n" + "@Suppress(\"NOTHING_TO_INLINE\")\n" + "public inline operator fun <T : Comparable<T>> set(\n" + " extension: com.google.protobuf.ExtensionLite<$message$, T>,\n" + " value: T\n" + ") {\n" + " setExtension(extension, value)\n" + "}\n\n", + "message", message_name); + + printer->Print( + "@kotlin.jvm.JvmSynthetic\n" + "@Suppress(\"NOTHING_TO_INLINE\")\n" + "public inline operator fun set(\n" + " extension: com.google.protobuf.ExtensionLite<$message$, " + "com.google.protobuf.ByteString>,\n" + " value: com.google.protobuf.ByteString\n" + ") {\n" + " setExtension(extension, value)\n" + "}\n\n", + "message", message_name); + + printer->Print( + "@kotlin.jvm.JvmSynthetic\n" + "@Suppress(\"NOTHING_TO_INLINE\")\n" + "public inline operator fun <T : com.google.protobuf.MessageLite> set(\n" + " extension: com.google.protobuf.ExtensionLite<$message$, T>,\n" + " value: T\n" + ") {\n" + " setExtension(extension, value)\n" + "}\n\n", + "message", message_name); + + printer->Print( + "@kotlin.jvm.JvmSynthetic\n" + "public fun <E> com.google.protobuf.kotlin.ExtensionList<E, " + "$message$>.add(value: E) {\n" + " _builder.addExtension(this.extension, value)\n" + "}\n\n", + "message", message_name); + + printer->Print( + "@kotlin.jvm.JvmSynthetic\n" + "@Suppress(\"NOTHING_TO_INLINE\")\n" + "public inline operator fun <E> " + "com.google.protobuf.kotlin.ExtensionList<E, " + "$message$>.plusAssign" + "(value: E) {\n" + " add(value)\n" + "}\n\n", + "message", message_name); + + printer->Print( + "@kotlin.jvm.JvmSynthetic\n" + "public fun <E> com.google.protobuf.kotlin.ExtensionList<E, " + "$message$>.addAll(values: Iterable<E>) {\n" + " for (value in values) {\n" + " add(value)\n" + " }\n" + "}\n\n", + "message", message_name); + + printer->Print( + "@kotlin.jvm.JvmSynthetic\n" + "@Suppress(\"NOTHING_TO_INLINE\")\n" + "public inline operator fun <E> " + "com.google.protobuf.kotlin.ExtensionList<E, " + "$message$>.plusAssign(values: " + "Iterable<E>) {\n" + " addAll(values)\n" + "}\n\n", + "message", message_name); + + printer->Print( + "@kotlin.jvm.JvmSynthetic\n" + "public operator fun <E> com.google.protobuf.kotlin.ExtensionList<E, " + "$message$>.set(index: Int, value: " + "E) {\n" + " _builder.setExtension(this.extension, index, value)\n" + "}\n\n", + "message", message_name); + + printer->Print( + "@kotlin.jvm.JvmSynthetic\n" + "@Suppress(\"NOTHING_TO_INLINE\")\n" + "public inline fun com.google.protobuf.kotlin.ExtensionList<*, " + "$message$>.clear() {\n" + " clear(extension)\n" + "}\n\n", + "message", message_name); +} + +void ImmutableMessageGenerator::GenerateAnyMethods(io::Printer* printer) { + printer->Print( + "private static String getTypeUrl(\n" + " java.lang.String typeUrlPrefix,\n" + " com.google.protobuf.Descriptors.Descriptor descriptor) {\n" + " return typeUrlPrefix.endsWith(\"/\")\n" + " ? typeUrlPrefix + descriptor.getFullName()\n" + " : typeUrlPrefix + \"/\" + descriptor.getFullName();\n" + "}\n" + "\n" + "private static String getTypeNameFromTypeUrl(\n" + " java.lang.String typeUrl) {\n" + " int pos = typeUrl.lastIndexOf('/');\n" + " return pos == -1 ? \"\" : typeUrl.substring(pos + 1);\n" + "}\n" + "\n" + "public static <T extends com.google.protobuf.Message> Any pack(\n" + " T message) {\n" + " return Any.newBuilder()\n" + " .setTypeUrl(getTypeUrl(\"type.googleapis.com\",\n" + " message.getDescriptorForType()))\n" + " .setValue(message.toByteString())\n" + " .build();\n" + "}\n" + "\n" + "/**\n" + " * Packs a message using the given type URL prefix. The type URL will\n" + " * be constructed by concatenating the message type's full name to the\n" + " * prefix with an optional \"/\" separator if the prefix doesn't end\n" + " * with \"/\" already.\n" + " */\n" + "public static <T extends com.google.protobuf.Message> Any pack(\n" + " T message, java.lang.String typeUrlPrefix) {\n" + " return Any.newBuilder()\n" + " .setTypeUrl(getTypeUrl(typeUrlPrefix,\n" + " message.getDescriptorForType()))\n" + " .setValue(message.toByteString())\n" + " .build();\n" + "}\n" + "\n" + "public <T extends com.google.protobuf.Message> boolean is(\n" + " java.lang.Class<T> clazz) {\n" + " T defaultInstance =\n" + " com.google.protobuf.Internal.getDefaultInstance(clazz);\n" + " return getTypeNameFromTypeUrl(getTypeUrl()).equals(\n" + " defaultInstance.getDescriptorForType().getFullName());\n" + "}\n" + "\n" + "private volatile com.google.protobuf.Message cachedUnpackValue;\n" + "\n" + "@java.lang.SuppressWarnings(\"unchecked\")\n" + "public <T extends com.google.protobuf.Message> T unpack(\n" + " java.lang.Class<T> clazz)\n" + " throws com.google.protobuf.InvalidProtocolBufferException {\n" + " boolean invalidClazz = false;\n" + " if (cachedUnpackValue != null) {\n" + " if (cachedUnpackValue.getClass() == clazz) {\n" + " return (T) cachedUnpackValue;\n" + " }\n" + " invalidClazz = true;\n" + " }\n" + " if (invalidClazz || !is(clazz)) {\n" + " throw new com.google.protobuf.InvalidProtocolBufferException(\n" + " \"Type of the Any message does not match the given class.\");\n" + " }\n" + " T defaultInstance =\n" + " com.google.protobuf.Internal.getDefaultInstance(clazz);\n" + " T result = (T) defaultInstance.getParserForType()\n" + " .parseFrom(getValue());\n" + " cachedUnpackValue = result;\n" + " return result;\n" + "}\n"); +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message.h new file mode 100644 index 00000000..7ee4e431 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message.h @@ -0,0 +1,153 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__ + +#include <map> +#include <string> +#include <compiler/java/java_field.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { +class Context; // context.h +class ClassNameResolver; // name_resolver.h +} // namespace java +} // namespace compiler +namespace io { +class Printer; // printer.h +} +} // namespace protobuf +} // namespace google + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +static const int kMaxStaticSize = 1 << 15; // aka 32k + +class MessageGenerator { + public: + explicit MessageGenerator(const Descriptor* descriptor); + virtual ~MessageGenerator(); + + // All static variables have to be declared at the top-level of the file + // so that we can control initialization order, which is important for + // DescriptorProto bootstrapping to work. + virtual void GenerateStaticVariables(io::Printer* printer, + int* bytecode_estimate) = 0; + + // Output code which initializes the static variables generated by + // GenerateStaticVariables(). Returns an estimate of bytecode size. + virtual int GenerateStaticVariableInitializers(io::Printer* printer) = 0; + + // Generate the class itself. + virtual void Generate(io::Printer* printer) = 0; + + // Generates the base interface that both the class and its builder + // implement + virtual void GenerateInterface(io::Printer* printer) = 0; + + // Generate code to register all contained extensions with an + // ExtensionRegistry. + virtual void GenerateExtensionRegistrationCode(io::Printer* printer) = 0; + virtual void GenerateKotlinDsl(io::Printer* printer) const = 0; + virtual void GenerateKotlinMembers(io::Printer* printer) const = 0; + virtual void GenerateTopLevelKotlinMembers(io::Printer* printer) const = 0; + + protected: + const Descriptor* descriptor_; + std::set<const OneofDescriptor*> oneofs_; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator); +}; + +class ImmutableMessageGenerator : public MessageGenerator { + public: + ImmutableMessageGenerator(const Descriptor* descriptor, Context* context); + virtual ~ImmutableMessageGenerator(); + + void Generate(io::Printer* printer) override; + void GenerateInterface(io::Printer* printer) override; + void GenerateExtensionRegistrationCode(io::Printer* printer) override; + void GenerateStaticVariables(io::Printer* printer, + int* bytecode_estimate) override; + + // Returns an estimate of the number of bytes the printed code will compile to + int GenerateStaticVariableInitializers(io::Printer* printer) override; + void GenerateKotlinDsl(io::Printer* printer) const override; + void GenerateKotlinMembers(io::Printer* printer) const override; + void GenerateTopLevelKotlinMembers(io::Printer* printer) const override; + + private: + void GenerateFieldAccessorTable(io::Printer* printer, int* bytecode_estimate); + + // Returns an estimate of the number of bytes the printed code will compile to + int GenerateFieldAccessorTableInitializer(io::Printer* printer); + + void GenerateMessageSerializationMethods(io::Printer* printer); + void GenerateParseFromMethods(io::Printer* printer); + void GenerateSerializeOneField(io::Printer* printer, + const FieldDescriptor* field); + void GenerateSerializeOneExtensionRange( + io::Printer* printer, const Descriptor::ExtensionRange* range); + + void GenerateBuilder(io::Printer* printer); + void GenerateIsInitialized(io::Printer* printer); + void GenerateDescriptorMethods(io::Printer* printer); + void GenerateInitializers(io::Printer* printer); + void GenerateEqualsAndHashCode(io::Printer* printer); + void GenerateParser(io::Printer* printer); + void GenerateParsingConstructor(io::Printer* printer); + void GenerateMutableCopy(io::Printer* printer); + void GenerateKotlinExtensions(io::Printer* printer) const; + void GenerateAnyMethods(io::Printer* printer); + + Context* context_; + ClassNameResolver* name_resolver_; + FieldGeneratorMap<ImmutableFieldGenerator> field_generators_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_H__ diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_builder.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_builder.cc new file mode 100644 index 00000000..ac72da8e --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_builder.cc @@ -0,0 +1,712 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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: dweis@google.com (Daniel Weis) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <compiler/java/java_message_builder.h> + +#include <algorithm> +#include <map> +#include <memory> +#include <vector> + +#include <compiler/java/java_context.h> +#include <compiler/java/java_doc_comment.h> +#include <compiler/java/java_enum.h> +#include <compiler/java/java_extension.h> +#include <compiler/java/java_generator_factory.h> +#include <compiler/java/java_helpers.h> +#include <compiler/java/java_name_resolver.h> +#include <descriptor.pb.h> +#include <io/coded_stream.h> +#include <io/printer.h> +#include <wire_format.h> +#include <stubs/strutil.h> +#include <stubs/substitute.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +namespace { +std::string MapValueImmutableClassdName(const Descriptor* descriptor, + ClassNameResolver* name_resolver) { + const FieldDescriptor* value_field = descriptor->FindFieldByName("value"); + GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, value_field->type()); + return name_resolver->GetImmutableClassName(value_field->message_type()); +} +} // namespace + +MessageBuilderGenerator::MessageBuilderGenerator(const Descriptor* descriptor, + Context* context) + : descriptor_(descriptor), + context_(context), + name_resolver_(context->GetNameResolver()), + field_generators_(descriptor, context_) { + GOOGLE_CHECK(HasDescriptorMethods(descriptor->file(), context->EnforceLite())) + << "Generator factory error: A non-lite message generator is used to " + "generate lite messages."; + for (int i = 0; i < descriptor_->field_count(); i++) { + if (IsRealOneof(descriptor_->field(i))) { + oneofs_.insert(descriptor_->field(i)->containing_oneof()); + } + } +} + +MessageBuilderGenerator::~MessageBuilderGenerator() {} + +void MessageBuilderGenerator::Generate(io::Printer* printer) { + WriteMessageDocComment(printer, descriptor_); + if (descriptor_->extension_range_count() > 0) { + printer->Print( + "public static final class Builder extends\n" + " com.google.protobuf.GeneratedMessage$ver$.ExtendableBuilder<\n" + " $classname$, Builder> implements\n" + " $extra_interfaces$\n" + " $classname$OrBuilder {\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_), + "extra_interfaces", ExtraBuilderInterfaces(descriptor_), "ver", + GeneratedCodeVersionSuffix()); + } else { + printer->Print( + "public static final class Builder extends\n" + " com.google.protobuf.GeneratedMessage$ver$.Builder<Builder> " + "implements\n" + " $extra_interfaces$\n" + " $classname$OrBuilder {\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_), + "extra_interfaces", ExtraBuilderInterfaces(descriptor_), "ver", + GeneratedCodeVersionSuffix()); + } + printer->Indent(); + + GenerateDescriptorMethods(printer); + GenerateCommonBuilderMethods(printer); + + if (context_->HasGeneratedMethods(descriptor_)) { + GenerateIsInitialized(printer); + GenerateBuilderParsingMethods(printer); + } + + // oneof + std::map<std::string, std::string> vars; + for (auto oneof : oneofs_) { + vars["oneof_name"] = context_->GetOneofGeneratorInfo(oneof)->name; + vars["oneof_capitalized_name"] = + context_->GetOneofGeneratorInfo(oneof)->capitalized_name; + vars["oneof_index"] = StrCat(oneof->index()); + // oneofCase_ and oneof_ + printer->Print(vars, + "private int $oneof_name$Case_ = 0;\n" + "private java.lang.Object $oneof_name$_;\n"); + // oneofCase() and clearOneof() + printer->Print(vars, + "public $oneof_capitalized_name$Case\n" + " get$oneof_capitalized_name$Case() {\n" + " return $oneof_capitalized_name$Case.forNumber(\n" + " $oneof_name$Case_);\n" + "}\n" + "\n" + "public Builder clear$oneof_capitalized_name$() {\n" + " $oneof_name$Case_ = 0;\n" + " $oneof_name$_ = null;\n"); + printer->Print(" onChanged();\n"); + printer->Print( + " return this;\n" + "}\n" + "\n"); + } + + // Integers for bit fields. + int totalBits = 0; + for (int i = 0; i < descriptor_->field_count(); i++) { + totalBits += + field_generators_.get(descriptor_->field(i)).GetNumBitsForBuilder(); + } + int totalInts = (totalBits + 31) / 32; + for (int i = 0; i < totalInts; i++) { + printer->Print("private int $bit_field_name$;\n", "bit_field_name", + GetBitFieldName(i)); + } + + for (int i = 0; i < descriptor_->field_count(); i++) { + printer->Print("\n"); + field_generators_.get(descriptor_->field(i)) + .GenerateBuilderMembers(printer); + } + + // Override methods declared in GeneratedMessage to return the concrete + // generated type so callsites won't depend on GeneratedMessage. This + // is needed to keep binary compatibility when we change generated code + // to subclass a different GeneratedMessage class (e.g., in v3.0.0 release + // we changed all generated code to subclass GeneratedMessageV3). + printer->Print( + "@java.lang.Override\n" + "public final Builder setUnknownFields(\n" + " final com.google.protobuf.UnknownFieldSet unknownFields) {\n" + " return super.setUnknownFields(unknownFields);\n" + "}\n" + "\n" + "@java.lang.Override\n" + "public final Builder mergeUnknownFields(\n" + " final com.google.protobuf.UnknownFieldSet unknownFields) {\n" + " return super.mergeUnknownFields(unknownFields);\n" + "}\n" + "\n"); + + printer->Print( + "\n" + "// @@protoc_insertion_point(builder_scope:$full_name$)\n", + "full_name", descriptor_->full_name()); + + printer->Outdent(); + printer->Print("}\n"); +} + +// =================================================================== + +void MessageBuilderGenerator::GenerateDescriptorMethods(io::Printer* printer) { + if (!descriptor_->options().no_standard_descriptor_accessor()) { + printer->Print( + "public static final com.google.protobuf.Descriptors.Descriptor\n" + " getDescriptor() {\n" + " return $fileclass$.internal_$identifier$_descriptor;\n" + "}\n" + "\n", + "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()), + "identifier", UniqueFileScopeIdentifier(descriptor_)); + } + std::vector<const FieldDescriptor*> map_fields; + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + if (GetJavaType(field) == JAVATYPE_MESSAGE && + IsMapEntry(field->message_type())) { + map_fields.push_back(field); + } + } + if (!map_fields.empty()) { + printer->Print( + "@SuppressWarnings({\"rawtypes\"})\n" + "protected com.google.protobuf.MapField internalGetMapField(\n" + " int number) {\n" + " switch (number) {\n"); + printer->Indent(); + printer->Indent(); + for (int i = 0; i < map_fields.size(); ++i) { + const FieldDescriptor* field = map_fields[i]; + const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field); + printer->Print( + "case $number$:\n" + " return internalGet$capitalized_name$();\n", + "number", StrCat(field->number()), "capitalized_name", + info->capitalized_name); + } + printer->Print( + "default:\n" + " throw new RuntimeException(\n" + " \"Invalid map field number: \" + number);\n"); + printer->Outdent(); + printer->Outdent(); + printer->Print( + " }\n" + "}\n"); + printer->Print( + "@SuppressWarnings({\"rawtypes\"})\n" + "protected com.google.protobuf.MapField internalGetMutableMapField(\n" + " int number) {\n" + " switch (number) {\n"); + printer->Indent(); + printer->Indent(); + for (int i = 0; i < map_fields.size(); ++i) { + const FieldDescriptor* field = map_fields[i]; + const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field); + printer->Print( + "case $number$:\n" + " return internalGetMutable$capitalized_name$();\n", + "number", StrCat(field->number()), "capitalized_name", + info->capitalized_name); + } + printer->Print( + "default:\n" + " throw new RuntimeException(\n" + " \"Invalid map field number: \" + number);\n"); + printer->Outdent(); + printer->Outdent(); + printer->Print( + " }\n" + "}\n"); + } + printer->Print( + "@java.lang.Override\n" + "protected com.google.protobuf.GeneratedMessage$ver$.FieldAccessorTable\n" + " internalGetFieldAccessorTable() {\n" + " return $fileclass$.internal_$identifier$_fieldAccessorTable\n" + " .ensureFieldAccessorsInitialized(\n" + " $classname$.class, $classname$.Builder.class);\n" + "}\n" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_), + "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()), + "identifier", UniqueFileScopeIdentifier(descriptor_), "ver", + GeneratedCodeVersionSuffix()); +} + +// =================================================================== + +void MessageBuilderGenerator::GenerateCommonBuilderMethods( + io::Printer* printer) { + printer->Print( + "// Construct using $classname$.newBuilder()\n" + "private Builder() {\n" + " maybeForceBuilderInitialization();\n" + "}\n" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + + printer->Print( + "private Builder(\n" + " com.google.protobuf.GeneratedMessage$ver$.BuilderParent parent) {\n" + " super(parent);\n" + " maybeForceBuilderInitialization();\n" + "}\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_), "ver", + GeneratedCodeVersionSuffix()); + + printer->Print( + "private void maybeForceBuilderInitialization() {\n" + " if (com.google.protobuf.GeneratedMessage$ver$\n" + " .alwaysUseFieldBuilders) {\n", + "ver", GeneratedCodeVersionSuffix()); + + printer->Indent(); + printer->Indent(); + for (int i = 0; i < descriptor_->field_count(); i++) { + if (!IsRealOneof(descriptor_->field(i))) { + field_generators_.get(descriptor_->field(i)) + .GenerateFieldBuilderInitializationCode(printer); + } + } + printer->Outdent(); + printer->Outdent(); + + printer->Print( + " }\n" + "}\n"); + + printer->Print( + "@java.lang.Override\n" + "public Builder clear() {\n" + " super.clear();\n"); + + printer->Indent(); + + for (int i = 0; i < descriptor_->field_count(); i++) { + if (!IsRealOneof(descriptor_->field(i))) { + field_generators_.get(descriptor_->field(i)) + .GenerateBuilderClearCode(printer); + } + } + + for (auto oneof : oneofs_) { + printer->Print( + "$oneof_name$Case_ = 0;\n" + "$oneof_name$_ = null;\n", + "oneof_name", context_->GetOneofGeneratorInfo(oneof)->name); + } + + printer->Outdent(); + + printer->Print( + " return this;\n" + "}\n" + "\n"); + + printer->Print( + "@java.lang.Override\n" + "public com.google.protobuf.Descriptors.Descriptor\n" + " getDescriptorForType() {\n" + " return $fileclass$.internal_$identifier$_descriptor;\n" + "}\n" + "\n", + "fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()), + "identifier", UniqueFileScopeIdentifier(descriptor_)); + + // LITE runtime implements this in GeneratedMessageLite. + printer->Print( + "@java.lang.Override\n" + "public $classname$ getDefaultInstanceForType() {\n" + " return $classname$.getDefaultInstance();\n" + "}\n" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + + printer->Print( + "@java.lang.Override\n" + "public $classname$ build() {\n" + " $classname$ result = buildPartial();\n" + " if (!result.isInitialized()) {\n" + " throw newUninitializedMessageException(result);\n" + " }\n" + " return result;\n" + "}\n" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + + printer->Print( + "@java.lang.Override\n" + "public $classname$ buildPartial() {\n" + " $classname$ result = new $classname$(this);\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + + printer->Indent(); + + int totalBuilderBits = 0; + int totalMessageBits = 0; + for (int i = 0; i < descriptor_->field_count(); i++) { + const ImmutableFieldGenerator& field = + field_generators_.get(descriptor_->field(i)); + totalBuilderBits += field.GetNumBitsForBuilder(); + totalMessageBits += field.GetNumBitsForMessage(); + } + int totalBuilderInts = (totalBuilderBits + 31) / 32; + int totalMessageInts = (totalMessageBits + 31) / 32; + + // Local vars for from and to bit fields to avoid accessing the builder and + // message over and over for these fields. Seems to provide a slight + // perforamance improvement in micro benchmark and this is also what proto1 + // code does. + for (int i = 0; i < totalBuilderInts; i++) { + printer->Print("int from_$bit_field_name$ = $bit_field_name$;\n", + "bit_field_name", GetBitFieldName(i)); + } + for (int i = 0; i < totalMessageInts; i++) { + printer->Print("int to_$bit_field_name$ = 0;\n", "bit_field_name", + GetBitFieldName(i)); + } + + // Output generation code for each field. + for (int i = 0; i < descriptor_->field_count(); i++) { + field_generators_.get(descriptor_->field(i)).GenerateBuildingCode(printer); + } + + // Copy the bit field results to the generated message + for (int i = 0; i < totalMessageInts; i++) { + printer->Print("result.$bit_field_name$ = to_$bit_field_name$;\n", + "bit_field_name", GetBitFieldName(i)); + } + + for (auto oneof : oneofs_) { + printer->Print("result.$oneof_name$Case_ = $oneof_name$Case_;\n", + "oneof_name", context_->GetOneofGeneratorInfo(oneof)->name); + } + + printer->Outdent(); + + printer->Print(" onBuilt();\n"); + + printer->Print( + " return result;\n" + "}\n" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + + // Override methods declared in GeneratedMessage to return the concrete + // generated type so callsites won't depend on GeneratedMessage. This + // is needed to keep binary compatibility when we change generated code + // to subclass a different GeneratedMessage class (e.g., in v3.0.0 release + // we changed all generated code to subclass GeneratedMessageV3). + printer->Print( + "@java.lang.Override\n" + "public Builder clone() {\n" + " return super.clone();\n" + "}\n" + "@java.lang.Override\n" + "public Builder setField(\n" + " com.google.protobuf.Descriptors.FieldDescriptor field,\n" + " java.lang.Object value) {\n" + " return super.setField(field, value);\n" + "}\n" + "@java.lang.Override\n" + "public Builder clearField(\n" + " com.google.protobuf.Descriptors.FieldDescriptor field) {\n" + " return super.clearField(field);\n" + "}\n" + "@java.lang.Override\n" + "public Builder clearOneof(\n" + " com.google.protobuf.Descriptors.OneofDescriptor oneof) {\n" + " return super.clearOneof(oneof);\n" + "}\n" + "@java.lang.Override\n" + "public Builder setRepeatedField(\n" + " com.google.protobuf.Descriptors.FieldDescriptor field,\n" + " int index, java.lang.Object value) {\n" + " return super.setRepeatedField(field, index, value);\n" + "}\n" + "@java.lang.Override\n" + "public Builder addRepeatedField(\n" + " com.google.protobuf.Descriptors.FieldDescriptor field,\n" + " java.lang.Object value) {\n" + " return super.addRepeatedField(field, value);\n" + "}\n"); + + if (descriptor_->extension_range_count() > 0) { + printer->Print( + "@java.lang.Override\n" + "public <Type> Builder setExtension(\n" + " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n" + " $classname$, Type> extension,\n" + " Type value) {\n" + " return super.setExtension(extension, value);\n" + "}\n" + "@java.lang.Override\n" + "public <Type> Builder setExtension(\n" + " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n" + " $classname$, java.util.List<Type>> extension,\n" + " int index, Type value) {\n" + " return super.setExtension(extension, index, value);\n" + "}\n" + "@java.lang.Override\n" + "public <Type> Builder addExtension(\n" + " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n" + " $classname$, java.util.List<Type>> extension,\n" + " Type value) {\n" + " return super.addExtension(extension, value);\n" + "}\n" + "@java.lang.Override\n" + "public <Type> Builder clearExtension(\n" + " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n" + " $classname$, ?> extension) {\n" + " return super.clearExtension(extension);\n" + "}\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + } + + // ----------------------------------------------------------------- + + if (context_->HasGeneratedMethods(descriptor_)) { + printer->Print( + "@java.lang.Override\n" + "public Builder mergeFrom(com.google.protobuf.Message other) {\n" + " if (other instanceof $classname$) {\n" + " return mergeFrom(($classname$)other);\n" + " } else {\n" + " super.mergeFrom(other);\n" + " return this;\n" + " }\n" + "}\n" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + + printer->Print( + "public Builder mergeFrom($classname$ other) {\n" + // Optimization: If other is the default instance, we know none of its + // fields are set so we can skip the merge. + " if (other == $classname$.getDefaultInstance()) return this;\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + printer->Indent(); + + for (int i = 0; i < descriptor_->field_count(); i++) { + if (!IsRealOneof(descriptor_->field(i))) { + field_generators_.get(descriptor_->field(i)) + .GenerateMergingCode(printer); + } + } + + // Merge oneof fields. + for (auto oneof : oneofs_) { + printer->Print("switch (other.get$oneof_capitalized_name$Case()) {\n", + "oneof_capitalized_name", + context_->GetOneofGeneratorInfo(oneof)->capitalized_name); + printer->Indent(); + for (int j = 0; j < oneof->field_count(); j++) { + const FieldDescriptor* field = oneof->field(j); + printer->Print("case $field_name$: {\n", "field_name", + ToUpper(field->name())); + printer->Indent(); + field_generators_.get(field).GenerateMergingCode(printer); + printer->Print("break;\n"); + printer->Outdent(); + printer->Print("}\n"); + } + printer->Print( + "case $cap_oneof_name$_NOT_SET: {\n" + " break;\n" + "}\n", + "cap_oneof_name", + ToUpper(context_->GetOneofGeneratorInfo(oneof)->name)); + printer->Outdent(); + printer->Print("}\n"); + } + + printer->Outdent(); + + // if message type has extensions + if (descriptor_->extension_range_count() > 0) { + printer->Print(" this.mergeExtensionFields(other);\n"); + } + + printer->Print(" this.mergeUnknownFields(other.unknownFields);\n"); + + printer->Print(" onChanged();\n"); + + printer->Print( + " return this;\n" + "}\n" + "\n"); + } +} + +// =================================================================== + +void MessageBuilderGenerator::GenerateBuilderParsingMethods( + io::Printer* printer) { + printer->Print( + "@java.lang.Override\n" + "public Builder mergeFrom(\n" + " com.google.protobuf.CodedInputStream input,\n" + " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" + " throws java.io.IOException {\n" + " $classname$ parsedMessage = null;\n" + " try {\n" + " parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);\n" + " } catch (com.google.protobuf.InvalidProtocolBufferException e) {\n" + " parsedMessage = ($classname$) e.getUnfinishedMessage();\n" + " throw e.unwrapIOException();\n" + " } finally {\n" + " if (parsedMessage != null) {\n" + " mergeFrom(parsedMessage);\n" + " }\n" + " }\n" + " return this;\n" + "}\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); +} + +// =================================================================== + +void MessageBuilderGenerator::GenerateIsInitialized(io::Printer* printer) { + printer->Print( + "@java.lang.Override\n" + "public final boolean isInitialized() {\n"); + printer->Indent(); + + // Check that all required fields in this message are set. + // TODO(kenton): We can optimize this when we switch to putting all the + // "has" fields into a single bitfield. + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field); + + if (field->is_required()) { + printer->Print( + "if (!has$name$()) {\n" + " return false;\n" + "}\n", + "name", info->capitalized_name); + } + } + + // Now check that all embedded messages are initialized. + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field); + if (GetJavaType(field) == JAVATYPE_MESSAGE && + HasRequiredFields(field->message_type())) { + switch (field->label()) { + case FieldDescriptor::LABEL_REQUIRED: + printer->Print( + "if (!get$name$().isInitialized()) {\n" + " return false;\n" + "}\n", + "type", + name_resolver_->GetImmutableClassName(field->message_type()), + "name", info->capitalized_name); + break; + case FieldDescriptor::LABEL_OPTIONAL: + printer->Print( + "if (has$name$()) {\n" + " if (!get$name$().isInitialized()) {\n" + " return false;\n" + " }\n" + "}\n", + "name", info->capitalized_name); + break; + case FieldDescriptor::LABEL_REPEATED: + if (IsMapEntry(field->message_type())) { + printer->Print( + "for ($type$ item : get$name$Map().values()) {\n" + " if (!item.isInitialized()) {\n" + " return false;\n" + " }\n" + "}\n", + "type", + MapValueImmutableClassdName(field->message_type(), + name_resolver_), + "name", info->capitalized_name); + } else { + printer->Print( + "for (int i = 0; i < get$name$Count(); i++) {\n" + " if (!get$name$(i).isInitialized()) {\n" + " return false;\n" + " }\n" + "}\n", + "type", + name_resolver_->GetImmutableClassName(field->message_type()), + "name", info->capitalized_name); + } + break; + } + } + } + + if (descriptor_->extension_range_count() > 0) { + printer->Print( + "if (!extensionsAreInitialized()) {\n" + " return false;\n" + "}\n"); + } + + printer->Outdent(); + + printer->Print( + " return true;\n" + "}\n" + "\n"); +} + +// =================================================================== + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_builder.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_builder.h new file mode 100644 index 00000000..7d6da17d --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_builder.h @@ -0,0 +1,89 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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: dweis@google.com (Daniel Weis) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_BUILDER_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_BUILDER_H__ + +#include <map> +#include <string> +#include <compiler/java/java_field.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { +class Context; // context.h +class ClassNameResolver; // name_resolver.h +} // namespace java +} // namespace compiler +namespace io { +class Printer; // printer.h +} +} // namespace protobuf +} // namespace google + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +class MessageBuilderGenerator { + public: + explicit MessageBuilderGenerator(const Descriptor* descriptor, + Context* context); + virtual ~MessageBuilderGenerator(); + + virtual void Generate(io::Printer* printer); + + private: + void GenerateCommonBuilderMethods(io::Printer* printer); + void GenerateDescriptorMethods(io::Printer* printer); + void GenerateBuilderParsingMethods(io::Printer* printer); + void GenerateIsInitialized(io::Printer* printer); + + const Descriptor* descriptor_; + Context* context_; + ClassNameResolver* name_resolver_; + FieldGeneratorMap<ImmutableFieldGenerator> field_generators_; + std::set<const OneofDescriptor*> oneofs_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageBuilderGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_BUILDER_H__ diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_builder_lite.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_builder_lite.cc new file mode 100644 index 00000000..83f5d072 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_builder_lite.cc @@ -0,0 +1,151 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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: dweis@google.com (Daniel Weis) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <compiler/java/java_message_builder_lite.h> + +#include <algorithm> +#include <map> +#include <memory> +#include <vector> + +#include <compiler/java/java_context.h> +#include <compiler/java/java_doc_comment.h> +#include <compiler/java/java_enum.h> +#include <compiler/java/java_extension.h> +#include <compiler/java/java_generator_factory.h> +#include <compiler/java/java_helpers.h> +#include <compiler/java/java_name_resolver.h> +#include <descriptor.pb.h> +#include <io/coded_stream.h> +#include <io/printer.h> +#include <wire_format.h> +#include <stubs/strutil.h> +#include <stubs/substitute.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +MessageBuilderLiteGenerator::MessageBuilderLiteGenerator( + const Descriptor* descriptor, Context* context) + : descriptor_(descriptor), + context_(context), + name_resolver_(context->GetNameResolver()), + field_generators_(descriptor, context_) { + GOOGLE_CHECK(!HasDescriptorMethods(descriptor->file(), context->EnforceLite())) + << "Generator factory error: A lite message generator is used to " + "generate non-lite messages."; + for (int i = 0; i < descriptor_->field_count(); i++) { + if (IsRealOneof(descriptor_->field(i))) { + oneofs_.insert(descriptor_->field(i)->containing_oneof()); + } + } +} + +MessageBuilderLiteGenerator::~MessageBuilderLiteGenerator() {} + +void MessageBuilderLiteGenerator::Generate(io::Printer* printer) { + WriteMessageDocComment(printer, descriptor_); + printer->Print( + "public static final class Builder extends\n" + " com.google.protobuf.GeneratedMessageLite.$extendible$Builder<\n" + " $classname$, Builder> implements\n" + " $extra_interfaces$\n" + " $classname$OrBuilder {\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_), + "extra_interfaces", ExtraBuilderInterfaces(descriptor_), "extendible", + descriptor_->extension_range_count() > 0 ? "Extendable" : ""); + printer->Indent(); + + GenerateCommonBuilderMethods(printer); + + // oneof + std::map<std::string, std::string> vars; + for (auto oneof : oneofs_) { + vars["oneof_name"] = context_->GetOneofGeneratorInfo(oneof)->name; + vars["oneof_capitalized_name"] = + context_->GetOneofGeneratorInfo(oneof)->capitalized_name; + vars["oneof_index"] = StrCat(oneof->index()); + + // oneofCase() and clearOneof() + printer->Print(vars, + "@java.lang.Override\n" + "public $oneof_capitalized_name$Case\n" + " get$oneof_capitalized_name$Case() {\n" + " return instance.get$oneof_capitalized_name$Case();\n" + "}\n" + "\n" + "public Builder clear$oneof_capitalized_name$() {\n" + " copyOnWrite();\n" + " instance.clear$oneof_capitalized_name$();\n" + " return this;\n" + "}\n" + "\n"); + } + + for (int i = 0; i < descriptor_->field_count(); i++) { + printer->Print("\n"); + field_generators_.get(descriptor_->field(i)) + .GenerateBuilderMembers(printer); + } + + printer->Print( + "\n" + "// @@protoc_insertion_point(builder_scope:$full_name$)\n", + "full_name", descriptor_->full_name()); + + printer->Outdent(); + printer->Print("}\n"); +} + +// =================================================================== + +void MessageBuilderLiteGenerator::GenerateCommonBuilderMethods( + io::Printer* printer) { + printer->Print( + "// Construct using $classname$.newBuilder()\n" + "private Builder() {\n" + " super(DEFAULT_INSTANCE);\n" + "}\n" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); +} + +// =================================================================== + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_builder_lite.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_builder_lite.h new file mode 100644 index 00000000..8ad4e94b --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_builder_lite.h @@ -0,0 +1,86 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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: dweis@google.com (Daniel Weis) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_BUILDER_LITE_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_BUILDER_LITE_H__ + +#include <map> +#include <string> +#include <compiler/java/java_field.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { +class Context; // context.h +class ClassNameResolver; // name_resolver.h +} // namespace java +} // namespace compiler +namespace io { +class Printer; // printer.h +} +} // namespace protobuf +} // namespace google + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +class MessageBuilderLiteGenerator { + public: + explicit MessageBuilderLiteGenerator(const Descriptor* descriptor, + Context* context); + virtual ~MessageBuilderLiteGenerator(); + + virtual void Generate(io::Printer* printer); + + private: + void GenerateCommonBuilderMethods(io::Printer* printer); + + const Descriptor* descriptor_; + Context* context_; + ClassNameResolver* name_resolver_; + FieldGeneratorMap<ImmutableFieldLiteGenerator> field_generators_; + std::set<const OneofDescriptor*> oneofs_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageBuilderLiteGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_BUILDER_LITE_H__ diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_field.cc new file mode 100644 index 00000000..394735d1 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_field.cc @@ -0,0 +1,1494 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <map> +#include <string> + +#include <compiler/java/java_context.h> +#include <compiler/java/java_doc_comment.h> +#include <compiler/java/java_helpers.h> +#include <compiler/java/java_message_field.h> +#include <compiler/java/java_name_resolver.h> +#include <io/printer.h> +#include <wire_format.h> +#include <stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + + +namespace { + +void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, + int builderBitIndex, const FieldGeneratorInfo* info, + ClassNameResolver* name_resolver, + std::map<std::string, std::string>* variables) { + SetCommonFieldVariables(descriptor, info, variables); + + (*variables)["type"] = + name_resolver->GetImmutableClassName(descriptor->message_type()); + (*variables)["kt_type"] = (*variables)["type"]; + (*variables)["mutable_type"] = + name_resolver->GetMutableClassName(descriptor->message_type()); + (*variables)["group_or_message"] = + (GetType(descriptor) == FieldDescriptor::TYPE_GROUP) ? "Group" + : "Message"; + // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported + // by the proto compiler + (*variables)["deprecation"] = + descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; + (*variables)["kt_deprecation"] = + descriptor->options().deprecated() + ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] + + " is deprecated\") " + : ""; + (*variables)["on_changed"] = "onChanged();"; + (*variables)["ver"] = GeneratedCodeVersionSuffix(); + (*variables)["get_parser"] = + ExposePublicParser(descriptor->message_type()->file()) ? "PARSER" + : "parser()"; + + if (HasHasbit(descriptor)) { + // For singular messages and builders, one bit is used for the hasField bit. + (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); + (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex); + + // Note that these have a trailing ";". + (*variables)["set_has_field_bit_message"] = + GenerateSetBit(messageBitIndex) + ";"; + (*variables)["set_has_field_bit_builder"] = + GenerateSetBit(builderBitIndex) + ";"; + (*variables)["clear_has_field_bit_builder"] = + GenerateClearBit(builderBitIndex) + ";"; + + (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex); + } else { + (*variables)["set_has_field_bit_message"] = ""; + (*variables)["set_has_field_bit_builder"] = ""; + (*variables)["clear_has_field_bit_builder"] = ""; + + (*variables)["is_field_present_message"] = + (*variables)["name"] + "_ != null"; + } + + // For repeated builders, one bit is used for whether the array is immutable. + (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex); + (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex); + (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex); + + // For repeated fields, one bit is used for whether the array is immutable + // in the parsing constructor. + (*variables)["get_mutable_bit_parser"] = + GenerateGetBitMutableLocal(builderBitIndex); + (*variables)["set_mutable_bit_parser"] = + GenerateSetBitMutableLocal(builderBitIndex); + + (*variables)["get_has_field_bit_from_local"] = + GenerateGetBitFromLocal(builderBitIndex); + (*variables)["set_has_field_bit_to_local"] = + GenerateSetBitToLocal(messageBitIndex); +} + +} // namespace + +// =================================================================== + +ImmutableMessageFieldGenerator::ImmutableMessageFieldGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, + Context* context) + : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) { + SetMessageVariables(descriptor, messageBitIndex, builderBitIndex, + context->GetFieldGeneratorInfo(descriptor), + name_resolver_, &variables_); +} + +ImmutableMessageFieldGenerator::~ImmutableMessageFieldGenerator() {} + +int ImmutableMessageFieldGenerator::GetNumBitsForMessage() const { + return HasHasbit(descriptor_) ? 1 : 0; +} + +int ImmutableMessageFieldGenerator::GetNumBitsForBuilder() const { + return GetNumBitsForMessage(); +} + +void ImmutableMessageFieldGenerator::GenerateInterfaceMembers( + io::Printer* printer) const { + // TODO(jonp): In the future, consider having a method specific to the + // interface so that builders can choose dynamically to either return a + // message or a nested builder, so that asking for the interface doesn't + // cause a message to ever be built. + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print(variables_, "$deprecation$boolean has$capitalized_name$();\n"); + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder();\n"); +} + +void ImmutableMessageFieldGenerator::GenerateMembers( + io::Printer* printer) const { + printer->Print(variables_, "private $type$ $name$_;\n"); + PrintExtraFieldInfo(variables_, printer); + + if (HasHasbit(descriptor_)) { + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return $get_has_field_bit_message$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" + " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public $type$OrBuilder " + "${$get$capitalized_name$OrBuilder$}$() {\n" + " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } else { + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return $name$_ != null;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" + " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public $type$OrBuilder " + "${$get$capitalized_name$OrBuilder$}$() {\n" + " return get$capitalized_name$();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } +} + +void ImmutableMessageFieldGenerator::PrintNestedBuilderCondition( + io::Printer* printer, const char* regular_case, + const char* nested_builder_case) const { + printer->Print(variables_, "if ($name$Builder_ == null) {\n"); + printer->Indent(); + printer->Print(variables_, regular_case); + printer->Outdent(); + printer->Print("} else {\n"); + printer->Indent(); + printer->Print(variables_, nested_builder_case); + printer->Outdent(); + printer->Print("}\n"); +} + +void ImmutableMessageFieldGenerator::PrintNestedBuilderFunction( + io::Printer* printer, const char* method_prototype, + const char* regular_case, const char* nested_builder_case, + const char* trailing_code) const { + printer->Print(variables_, method_prototype); + printer->Annotate("{", "}", descriptor_); + printer->Print(" {\n"); + printer->Indent(); + PrintNestedBuilderCondition(printer, regular_case, nested_builder_case); + if (trailing_code != NULL) { + printer->Print(variables_, trailing_code); + } + printer->Outdent(); + printer->Print("}\n"); +} + +void ImmutableMessageFieldGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + // When using nested-builders, the code initially works just like the + // non-nested builder case. It only creates a nested builder lazily on + // demand and then forever delegates to it after creation. + + bool has_hasbit = HasHasbit(descriptor_); + + printer->Print(variables_, "private $type$ $name$_;\n"); + + printer->Print(variables_, + // If this builder is non-null, it is used and the other fields + // are ignored. + "private com.google.protobuf.SingleFieldBuilder$ver$<\n" + " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;" + "\n"); + + // The comments above the methods below are based on a hypothetical + // field of type "Field" called "Field". + + // boolean hasField() + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + if (has_hasbit) { + printer->Print( + variables_, + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return $get_has_field_bit_builder$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } else { + printer->Print( + variables_, + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return $name$Builder_ != null || $name$_ != null;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } + + // Field getField() + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + PrintNestedBuilderFunction( + printer, "$deprecation$public $type$ ${$get$capitalized_name$$}$()", + "return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n", + "return $name$Builder_.getMessage();\n", NULL); + + // Field.Builder setField(Field value) + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction( + printer, + "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value)", + + "if (value == null) {\n" + " throw new NullPointerException();\n" + "}\n" + "$name$_ = value;\n" + "$on_changed$\n", + + "$name$Builder_.setMessage(value);\n", + + "$set_has_field_bit_builder$\n" + "return this;\n"); + + // Field.Builder setField(Field.Builder builderForValue) + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction( + printer, + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" + " $type$.Builder builderForValue)", + + "$name$_ = builderForValue.build();\n" + "$on_changed$\n", + + "$name$Builder_.setMessage(builderForValue.build());\n", + + "$set_has_field_bit_builder$\n" + "return this;\n"); + + // Field.Builder mergeField(Field value) + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction( + printer, + "$deprecation$public Builder ${$merge$capitalized_name$$}$($type$ value)", + + has_hasbit + ? "if ($get_has_field_bit_builder$ &&\n" + " $name$_ != null &&\n" + " $name$_ != $type$.getDefaultInstance()) {\n" + " $name$_ =\n" + " $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n" + "} else {\n" + " $name$_ = value;\n" + "}\n" + "$on_changed$\n" + : "if ($name$_ != null) {\n" + " $name$_ =\n" + " $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n" + "} else {\n" + " $name$_ = value;\n" + "}\n" + "$on_changed$\n", + + "$name$Builder_.mergeFrom(value);\n", + + "$set_has_field_bit_builder$\n" + "return this;\n"); + + // Field.Builder clearField() + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction( + printer, "$deprecation$public Builder ${$clear$capitalized_name$$}$()", + + "$name$_ = null;\n" + "$on_changed$\n", + + has_hasbit ? "$name$Builder_.clear();\n" + : "$name$_ = null;\n" + "$name$Builder_ = null;\n", + + "$clear_has_field_bit_builder$\n" + "return this;\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$.Builder " + "${$get$capitalized_name$Builder$}$() {\n" + " $set_has_field_bit_builder$\n" + " $on_changed$\n" + " return get$capitalized_name$FieldBuilder().getBuilder();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$OrBuilder " + "${$get$capitalized_name$OrBuilder$}$() {\n" + " if ($name$Builder_ != null) {\n" + " return $name$Builder_.getMessageOrBuilder();\n" + " } else {\n" + " return $name$_ == null ?\n" + " $type$.getDefaultInstance() : $name$_;\n" + " }\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "private com.google.protobuf.SingleFieldBuilder$ver$<\n" + " $type$, $type$.Builder, $type$OrBuilder> \n" + " get$capitalized_name$FieldBuilder() {\n" + " if ($name$Builder_ == null) {\n" + " $name$Builder_ = new com.google.protobuf.SingleFieldBuilder$ver$<\n" + " $type$, $type$.Builder, $type$OrBuilder>(\n" + " get$capitalized_name$(),\n" + " getParentForChildren(),\n" + " isClean());\n" + " $name$_ = null;\n" + " }\n" + " return $name$Builder_;\n" + "}\n"); +} + +void ImmutableMessageFieldGenerator::GenerateKotlinDslMembers( + io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$kt_deprecation$public var $kt_name$: $kt_type$\n" + " @JvmName(\"${$get$kt_capitalized_name$$}$\")\n" + " get() = $kt_dsl_builder$.${$get$capitalized_name$$}$()\n" + " @JvmName(\"${$set$kt_capitalized_name$$}$\")\n" + " set(value) {\n" + " $kt_dsl_builder$.${$set$capitalized_name$$}$(value)\n" + " }\n"); + + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ false); + printer->Print(variables_, + "public fun ${$clear$kt_capitalized_name$$}$() {\n" + " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n" + "}\n"); + + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print( + variables_, + "public fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n" + " return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n" + "}\n"); +} + +void ImmutableMessageFieldGenerator::GenerateFieldBuilderInitializationCode( + io::Printer* printer) const { + if (HasHasbit(descriptor_)) { + printer->Print(variables_, "get$capitalized_name$FieldBuilder();\n"); + } +} + +void ImmutableMessageFieldGenerator::GenerateInitializationCode( + io::Printer* printer) const {} + +void ImmutableMessageFieldGenerator::GenerateBuilderClearCode( + io::Printer* printer) const { + if (HasHasbit(descriptor_)) { + PrintNestedBuilderCondition(printer, "$name$_ = null;\n", + + "$name$Builder_.clear();\n"); + printer->Print(variables_, "$clear_has_field_bit_builder$\n"); + } else { + PrintNestedBuilderCondition(printer, "$name$_ = null;\n", + + "$name$_ = null;\n" + "$name$Builder_ = null;\n"); + } +} + +void ImmutableMessageFieldGenerator::GenerateMergingCode( + io::Printer* printer) const { + printer->Print(variables_, + "if (other.has$capitalized_name$()) {\n" + " merge$capitalized_name$(other.get$capitalized_name$());\n" + "}\n"); +} + +void ImmutableMessageFieldGenerator::GenerateBuildingCode( + io::Printer* printer) const { + if (HasHasbit(descriptor_)) { + printer->Print(variables_, "if ($get_has_field_bit_from_local$) {\n"); + printer->Indent(); + PrintNestedBuilderCondition(printer, "result.$name$_ = $name$_;\n", + "result.$name$_ = $name$Builder_.build();\n"); + printer->Outdent(); + printer->Print(variables_, + " $set_has_field_bit_to_local$;\n" + "}\n"); + } else { + PrintNestedBuilderCondition(printer, "result.$name$_ = $name$_;\n", + "result.$name$_ = $name$Builder_.build();\n"); + } +} + +void ImmutableMessageFieldGenerator::GenerateParsingCode( + io::Printer* printer) const { + printer->Print(variables_, + "$type$.Builder subBuilder = null;\n" + "if ($is_field_present_message$) {\n" + " subBuilder = $name$_.toBuilder();\n" + "}\n"); + + if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) { + printer->Print(variables_, + "$name$_ = input.readGroup($number$, $type$.$get_parser$,\n" + " extensionRegistry);\n"); + } else { + printer->Print(variables_, + "$name$_ = input.readMessage($type$.$get_parser$, " + "extensionRegistry);\n"); + } + + printer->Print(variables_, + "if (subBuilder != null) {\n" + " subBuilder.mergeFrom($name$_);\n" + " $name$_ = subBuilder.buildPartial();\n" + "}\n" + "$set_has_field_bit_message$\n"); +} + +void ImmutableMessageFieldGenerator::GenerateParsingDoneCode( + io::Printer* printer) const { + // noop for messages. +} + +void ImmutableMessageFieldGenerator::GenerateSerializationCode( + io::Printer* printer) const { + printer->Print( + variables_, + "if ($is_field_present_message$) {\n" + " output.write$group_or_message$($number$, get$capitalized_name$());\n" + "}\n"); +} + +void ImmutableMessageFieldGenerator::GenerateSerializedSizeCode( + io::Printer* printer) const { + printer->Print( + variables_, + "if ($is_field_present_message$) {\n" + " size += com.google.protobuf.CodedOutputStream\n" + " .compute$group_or_message$Size($number$, get$capitalized_name$());\n" + "}\n"); +} + +void ImmutableMessageFieldGenerator::GenerateEqualsCode( + io::Printer* printer) const { + printer->Print(variables_, + "if (!get$capitalized_name$()\n" + " .equals(other.get$capitalized_name$())) return false;\n"); +} + +void ImmutableMessageFieldGenerator::GenerateHashCode( + io::Printer* printer) const { + printer->Print(variables_, + "hash = (37 * hash) + $constant_name$;\n" + "hash = (53 * hash) + get$capitalized_name$().hashCode();\n"); +} + +std::string ImmutableMessageFieldGenerator::GetBoxedType() const { + return name_resolver_->GetImmutableClassName(descriptor_->message_type()); +} + +// =================================================================== + +ImmutableMessageOneofFieldGenerator::ImmutableMessageOneofFieldGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, + Context* context) + : ImmutableMessageFieldGenerator(descriptor, messageBitIndex, + builderBitIndex, context) { + const OneofGeneratorInfo* info = + context->GetOneofGeneratorInfo(descriptor->containing_oneof()); + SetCommonOneofVariables(descriptor, info, &variables_); +} + +ImmutableMessageOneofFieldGenerator::~ImmutableMessageOneofFieldGenerator() {} + +void ImmutableMessageOneofFieldGenerator::GenerateMembers( + io::Printer* printer) const { + PrintExtraFieldInfo(variables_, printer); + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return $has_oneof_case_message$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" + " if ($has_oneof_case_message$) {\n" + " return ($type$) $oneof_name$_;\n" + " }\n" + " return $type$.getDefaultInstance();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public $type$OrBuilder " + "${$get$capitalized_name$OrBuilder$}$() {\n" + " if ($has_oneof_case_message$) {\n" + " return ($type$) $oneof_name$_;\n" + " }\n" + " return $type$.getDefaultInstance();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +void ImmutableMessageOneofFieldGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + // When using nested-builders, the code initially works just like the + // non-nested builder case. It only creates a nested builder lazily on + // demand and then forever delegates to it after creation. + printer->Print(variables_, + // If this builder is non-null, it is used and the other fields + // are ignored. + "private com.google.protobuf.SingleFieldBuilder$ver$<\n" + " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;" + "\n"); + + // The comments above the methods below are based on a hypothetical + // field of type "Field" called "Field". + + // boolean hasField() + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return $has_oneof_case_message$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + // Field getField() + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + PrintNestedBuilderFunction( + printer, + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$()", + + "if ($has_oneof_case_message$) {\n" + " return ($type$) $oneof_name$_;\n" + "}\n" + "return $type$.getDefaultInstance();\n", + + "if ($has_oneof_case_message$) {\n" + " return $name$Builder_.getMessage();\n" + "}\n" + "return $type$.getDefaultInstance();\n", + + NULL); + + // Field.Builder setField(Field value) + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction( + printer, + "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value)", + + "if (value == null) {\n" + " throw new NullPointerException();\n" + "}\n" + "$oneof_name$_ = value;\n" + "$on_changed$\n", + + "$name$Builder_.setMessage(value);\n", + + "$set_oneof_case_message$;\n" + "return this;\n"); + + // Field.Builder setField(Field.Builder builderForValue) + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction( + printer, + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" + " $type$.Builder builderForValue)", + + "$oneof_name$_ = builderForValue.build();\n" + "$on_changed$\n", + + "$name$Builder_.setMessage(builderForValue.build());\n", + + "$set_oneof_case_message$;\n" + "return this;\n"); + + // Field.Builder mergeField(Field value) + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction( + printer, + "$deprecation$public Builder ${$merge$capitalized_name$$}$($type$ value)", + + "if ($has_oneof_case_message$ &&\n" + " $oneof_name$_ != $type$.getDefaultInstance()) {\n" + " $oneof_name$_ = $type$.newBuilder(($type$) $oneof_name$_)\n" + " .mergeFrom(value).buildPartial();\n" + "} else {\n" + " $oneof_name$_ = value;\n" + "}\n" + "$on_changed$\n", + + "if ($has_oneof_case_message$) {\n" + " $name$Builder_.mergeFrom(value);\n" + "}\n" + "$name$Builder_.setMessage(value);\n", + + "$set_oneof_case_message$;\n" + "return this;\n"); + + // Field.Builder clearField() + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction( + printer, "$deprecation$public Builder ${$clear$capitalized_name$$}$()", + + "if ($has_oneof_case_message$) {\n" + " $clear_oneof_case_message$;\n" + " $oneof_name$_ = null;\n" + " $on_changed$\n" + "}\n", + + "if ($has_oneof_case_message$) {\n" + " $clear_oneof_case_message$;\n" + " $oneof_name$_ = null;\n" + "}\n" + "$name$Builder_.clear();\n", + + "return this;\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$.Builder " + "${$get$capitalized_name$Builder$}$() {\n" + " return get$capitalized_name$FieldBuilder().getBuilder();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public $type$OrBuilder " + "${$get$capitalized_name$OrBuilder$}$() {\n" + " if (($has_oneof_case_message$) && ($name$Builder_ != null)) {\n" + " return $name$Builder_.getMessageOrBuilder();\n" + " } else {\n" + " if ($has_oneof_case_message$) {\n" + " return ($type$) $oneof_name$_;\n" + " }\n" + " return $type$.getDefaultInstance();\n" + " }\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "private com.google.protobuf.SingleFieldBuilder$ver$<\n" + " $type$, $type$.Builder, $type$OrBuilder> \n" + " ${$get$capitalized_name$FieldBuilder$}$() {\n" + " if ($name$Builder_ == null) {\n" + " if (!($has_oneof_case_message$)) {\n" + " $oneof_name$_ = $type$.getDefaultInstance();\n" + " }\n" + " $name$Builder_ = new com.google.protobuf.SingleFieldBuilder$ver$<\n" + " $type$, $type$.Builder, $type$OrBuilder>(\n" + " ($type$) $oneof_name$_,\n" + " getParentForChildren(),\n" + " isClean());\n" + " $oneof_name$_ = null;\n" + " }\n" + " $set_oneof_case_message$;\n" + " $on_changed$;\n" + " return $name$Builder_;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +void ImmutableMessageOneofFieldGenerator::GenerateBuildingCode( + io::Printer* printer) const { + printer->Print(variables_, "if ($has_oneof_case_message$) {\n"); + printer->Indent(); + + PrintNestedBuilderCondition( + printer, "result.$oneof_name$_ = $oneof_name$_;\n", + + "result.$oneof_name$_ = $name$Builder_.build();\n"); + + printer->Outdent(); + printer->Print("}\n"); +} + +void ImmutableMessageOneofFieldGenerator::GenerateMergingCode( + io::Printer* printer) const { + printer->Print(variables_, + "merge$capitalized_name$(other.get$capitalized_name$());\n"); +} + +void ImmutableMessageOneofFieldGenerator::GenerateParsingCode( + io::Printer* printer) const { + printer->Print(variables_, + "$type$.Builder subBuilder = null;\n" + "if ($has_oneof_case_message$) {\n" + " subBuilder = (($type$) $oneof_name$_).toBuilder();\n" + "}\n"); + + if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) { + printer->Print( + variables_, + "$oneof_name$_ = input.readGroup($number$, $type$.$get_parser$,\n" + " extensionRegistry);\n"); + } else { + printer->Print( + variables_, + "$oneof_name$_ =\n" + " input.readMessage($type$.$get_parser$, extensionRegistry);\n"); + } + + printer->Print(variables_, + "if (subBuilder != null) {\n" + " subBuilder.mergeFrom(($type$) $oneof_name$_);\n" + " $oneof_name$_ = subBuilder.buildPartial();\n" + "}\n"); + printer->Print(variables_, "$set_oneof_case_message$;\n"); +} + +void ImmutableMessageOneofFieldGenerator::GenerateSerializationCode( + io::Printer* printer) const { + printer->Print( + variables_, + "if ($has_oneof_case_message$) {\n" + " output.write$group_or_message$($number$, ($type$) $oneof_name$_);\n" + "}\n"); +} + +void ImmutableMessageOneofFieldGenerator::GenerateSerializedSizeCode( + io::Printer* printer) const { + printer->Print( + variables_, + "if ($has_oneof_case_message$) {\n" + " size += com.google.protobuf.CodedOutputStream\n" + " .compute$group_or_message$Size($number$, ($type$) $oneof_name$_);\n" + "}\n"); +} + +// =================================================================== + +RepeatedImmutableMessageFieldGenerator::RepeatedImmutableMessageFieldGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, + Context* context) + : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) { + SetMessageVariables(descriptor, messageBitIndex, builderBitIndex, + context->GetFieldGeneratorInfo(descriptor), + name_resolver_, &variables_); +} + +RepeatedImmutableMessageFieldGenerator:: + ~RepeatedImmutableMessageFieldGenerator() {} + +int RepeatedImmutableMessageFieldGenerator::GetNumBitsForMessage() const { + return 0; +} + +int RepeatedImmutableMessageFieldGenerator::GetNumBitsForBuilder() const { + return 1; +} + +void RepeatedImmutableMessageFieldGenerator::GenerateInterfaceMembers( + io::Printer* printer) const { + // TODO(jonp): In the future, consider having methods specific to the + // interface so that builders can choose dynamically to either return a + // message or a nested builder, so that asking for the interface doesn't + // cause a message to ever be built. + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$java.util.List<$type$> \n" + " get$capitalized_name$List();\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$$type$ get$capitalized_name$(int index);\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$int get$capitalized_name$Count();\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$java.util.List<? extends $type$OrBuilder> \n" + " get$capitalized_name$OrBuilderList();\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder(\n" + " int index);\n"); +} + +void RepeatedImmutableMessageFieldGenerator::GenerateMembers( + io::Printer* printer) const { + printer->Print(variables_, "private java.util.List<$type$> $name$_;\n"); + PrintExtraFieldInfo(variables_, printer); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public java.util.List<$type$> " + "${$get$capitalized_name$List$}$() {\n" + " return $name$_;\n" // note: unmodifiable list + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public java.util.List<? extends $type$OrBuilder> \n" + " ${$get$capitalized_name$OrBuilderList$}$() {\n" + " return $name$_;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" + " return $name$_.size();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" + " return $name$_.get(index);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public $type$OrBuilder " + "${$get$capitalized_name$OrBuilder$}$(\n" + " int index) {\n" + " return $name$_.get(index);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +void RepeatedImmutableMessageFieldGenerator::PrintNestedBuilderCondition( + io::Printer* printer, const char* regular_case, + const char* nested_builder_case) const { + printer->Print(variables_, "if ($name$Builder_ == null) {\n"); + printer->Indent(); + printer->Print(variables_, regular_case); + printer->Outdent(); + printer->Print("} else {\n"); + printer->Indent(); + printer->Print(variables_, nested_builder_case); + printer->Outdent(); + printer->Print("}\n"); +} + +void RepeatedImmutableMessageFieldGenerator::PrintNestedBuilderFunction( + io::Printer* printer, const char* method_prototype, + const char* regular_case, const char* nested_builder_case, + const char* trailing_code) const { + printer->Print(variables_, method_prototype); + printer->Annotate("{", "}", descriptor_); + printer->Print(" {\n"); + printer->Indent(); + PrintNestedBuilderCondition(printer, regular_case, nested_builder_case); + if (trailing_code != NULL) { + printer->Print(variables_, trailing_code); + } + printer->Outdent(); + printer->Print("}\n"); +} + +void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + // When using nested-builders, the code initially works just like the + // non-nested builder case. It only creates a nested builder lazily on + // demand and then forever delegates to it after creation. + + printer->Print( + variables_, + // Used when the builder is null. + // One field is the list and the other field keeps track of whether the + // list is immutable. If it's immutable, the invariant is that it must + // either an instance of Collections.emptyList() or it's an ArrayList + // wrapped in a Collections.unmodifiableList() wrapper and nobody else has + // a reference to the underlying ArrayList. This invariant allows us to + // share instances of lists between protocol buffers avoiding expensive + // memory allocations. Note, immutable is a strong guarantee here -- not + // just that the list cannot be modified via the reference but that the + // list can never be modified. + "private java.util.List<$type$> $name$_ =\n" + " java.util.Collections.emptyList();\n" + + "private void ensure$capitalized_name$IsMutable() {\n" + " if (!$get_mutable_bit_builder$) {\n" + " $name$_ = new java.util.ArrayList<$type$>($name$_);\n" + " $set_mutable_bit_builder$;\n" + " }\n" + "}\n" + "\n"); + + printer->Print( + variables_, + // If this builder is non-null, it is used and the other fields are + // ignored. + "private com.google.protobuf.RepeatedFieldBuilder$ver$<\n" + " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;\n" + "\n"); + + // The comments above the methods below are based on a hypothetical + // repeated field of type "Field" called "RepeatedField". + + // List<Field> getRepeatedFieldList() + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction( + printer, + "$deprecation$public java.util.List<$type$> " + "${$get$capitalized_name$List$}$()", + + "return java.util.Collections.unmodifiableList($name$_);\n", + "return $name$Builder_.getMessageList();\n", + + NULL); + + // int getRepeatedFieldCount() + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction( + printer, "$deprecation$public int ${$get$capitalized_name$Count$}$()", + + "return $name$_.size();\n", "return $name$Builder_.getCount();\n", + + NULL); + + // Field getRepeatedField(int index) + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction( + printer, + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index)", + + "return $name$_.get(index);\n", + + "return $name$Builder_.getMessage(index);\n", + + NULL); + + // Builder setRepeatedField(int index, Field value) + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction( + printer, + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" + " int index, $type$ value)", + "if (value == null) {\n" + " throw new NullPointerException();\n" + "}\n" + "ensure$capitalized_name$IsMutable();\n" + "$name$_.set(index, value);\n" + "$on_changed$\n", + "$name$Builder_.setMessage(index, value);\n", "return this;\n"); + + // Builder setRepeatedField(int index, Field.Builder builderForValue) + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction( + printer, + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" + " int index, $type$.Builder builderForValue)", + + "ensure$capitalized_name$IsMutable();\n" + "$name$_.set(index, builderForValue.build());\n" + "$on_changed$\n", + + "$name$Builder_.setMessage(index, builderForValue.build());\n", + + "return this;\n"); + + // Builder addRepeatedField(Field value) + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction( + printer, + "$deprecation$public Builder ${$add$capitalized_name$$}$($type$ value)", + + "if (value == null) {\n" + " throw new NullPointerException();\n" + "}\n" + "ensure$capitalized_name$IsMutable();\n" + "$name$_.add(value);\n" + + "$on_changed$\n", + + "$name$Builder_.addMessage(value);\n", + + "return this;\n"); + + // Builder addRepeatedField(int index, Field value) + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction( + printer, + "$deprecation$public Builder ${$add$capitalized_name$$}$(\n" + " int index, $type$ value)", + + "if (value == null) {\n" + " throw new NullPointerException();\n" + "}\n" + "ensure$capitalized_name$IsMutable();\n" + "$name$_.add(index, value);\n" + "$on_changed$\n", + + "$name$Builder_.addMessage(index, value);\n", + + "return this;\n"); + + // Builder addRepeatedField(Field.Builder builderForValue) + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction( + printer, + "$deprecation$public Builder ${$add$capitalized_name$$}$(\n" + " $type$.Builder builderForValue)", + + "ensure$capitalized_name$IsMutable();\n" + "$name$_.add(builderForValue.build());\n" + "$on_changed$\n", + + "$name$Builder_.addMessage(builderForValue.build());\n", + + "return this;\n"); + + // Builder addRepeatedField(int index, Field.Builder builderForValue) + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction( + printer, + "$deprecation$public Builder ${$add$capitalized_name$$}$(\n" + " int index, $type$.Builder builderForValue)", + + "ensure$capitalized_name$IsMutable();\n" + "$name$_.add(index, builderForValue.build());\n" + "$on_changed$\n", + + "$name$Builder_.addMessage(index, builderForValue.build());\n", + + "return this;\n"); + + // Builder addAllRepeatedField(Iterable<Field> values) + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction( + printer, + "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n" + " java.lang.Iterable<? extends $type$> values)", + + "ensure$capitalized_name$IsMutable();\n" + "com.google.protobuf.AbstractMessageLite.Builder.addAll(\n" + " values, $name$_);\n" + "$on_changed$\n", + + "$name$Builder_.addAllMessages(values);\n", + + "return this;\n"); + + // Builder clearAllRepeatedField() + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction( + printer, "$deprecation$public Builder ${$clear$capitalized_name$$}$()", + + "$name$_ = java.util.Collections.emptyList();\n" + "$clear_mutable_bit_builder$;\n" + "$on_changed$\n", + + "$name$Builder_.clear();\n", + + "return this;\n"); + + // Builder removeRepeatedField(int index) + WriteFieldDocComment(printer, descriptor_); + PrintNestedBuilderFunction( + printer, + "$deprecation$public Builder ${$remove$capitalized_name$$}$(int index)", + + "ensure$capitalized_name$IsMutable();\n" + "$name$_.remove(index);\n" + "$on_changed$\n", + + "$name$Builder_.remove(index);\n", + + "return this;\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$public $type$.Builder ${$get$capitalized_name$Builder$}$(\n" + " int index) {\n" + " return get$capitalized_name$FieldBuilder().getBuilder(index);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$OrBuilder " + "${$get$capitalized_name$OrBuilder$}$(\n" + " int index) {\n" + " if ($name$Builder_ == null) {\n" + " return $name$_.get(index);" + " } else {\n" + " return $name$Builder_.getMessageOrBuilder(index);\n" + " }\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$public java.util.List<? extends $type$OrBuilder> \n" + " ${$get$capitalized_name$OrBuilderList$}$() {\n" + " if ($name$Builder_ != null) {\n" + " return $name$Builder_.getMessageOrBuilderList();\n" + " } else {\n" + " return java.util.Collections.unmodifiableList($name$_);\n" + " }\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$.Builder " + "${$add$capitalized_name$Builder$}$() {\n" + " return get$capitalized_name$FieldBuilder().addBuilder(\n" + " $type$.getDefaultInstance());\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$public $type$.Builder ${$add$capitalized_name$Builder$}$(\n" + " int index) {\n" + " return get$capitalized_name$FieldBuilder().addBuilder(\n" + " index, $type$.getDefaultInstance());\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$public java.util.List<$type$.Builder> \n" + " ${$get$capitalized_name$BuilderList$}$() {\n" + " return get$capitalized_name$FieldBuilder().getBuilderList();\n" + "}\n" + "private com.google.protobuf.RepeatedFieldBuilder$ver$<\n" + " $type$, $type$.Builder, $type$OrBuilder> \n" + " get$capitalized_name$FieldBuilder() {\n" + " if ($name$Builder_ == null) {\n" + " $name$Builder_ = new " + "com.google.protobuf.RepeatedFieldBuilder$ver$<\n" + " $type$, $type$.Builder, $type$OrBuilder>(\n" + " $name$_,\n" + " $get_mutable_bit_builder$,\n" + " getParentForChildren(),\n" + " isClean());\n" + " $name$_ = null;\n" + " }\n" + " return $name$Builder_;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +void RepeatedImmutableMessageFieldGenerator:: + GenerateFieldBuilderInitializationCode(io::Printer* printer) const { + printer->Print(variables_, "get$capitalized_name$FieldBuilder();\n"); +} + +void RepeatedImmutableMessageFieldGenerator::GenerateInitializationCode( + io::Printer* printer) const { + printer->Print(variables_, "$name$_ = java.util.Collections.emptyList();\n"); +} + +void RepeatedImmutableMessageFieldGenerator::GenerateBuilderClearCode( + io::Printer* printer) const { + PrintNestedBuilderCondition(printer, + "$name$_ = java.util.Collections.emptyList();\n" + "$clear_mutable_bit_builder$;\n", + + "$name$Builder_.clear();\n"); +} + +void RepeatedImmutableMessageFieldGenerator::GenerateMergingCode( + io::Printer* printer) const { + // The code below does two optimizations (non-nested builder case): + // 1. If the other list is empty, there's nothing to do. This ensures we + // don't allocate a new array if we already have an immutable one. + // 2. If the other list is non-empty and our current list is empty, we can + // reuse the other list which is guaranteed to be immutable. + PrintNestedBuilderCondition( + printer, + "if (!other.$name$_.isEmpty()) {\n" + " if ($name$_.isEmpty()) {\n" + " $name$_ = other.$name$_;\n" + " $clear_mutable_bit_builder$;\n" + " } else {\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.addAll(other.$name$_);\n" + " }\n" + " $on_changed$\n" + "}\n", + + "if (!other.$name$_.isEmpty()) {\n" + " if ($name$Builder_.isEmpty()) {\n" + " $name$Builder_.dispose();\n" + " $name$Builder_ = null;\n" + " $name$_ = other.$name$_;\n" + " $clear_mutable_bit_builder$;\n" + " $name$Builder_ = \n" + " com.google.protobuf.GeneratedMessage$ver$.alwaysUseFieldBuilders " + "?\n" + " get$capitalized_name$FieldBuilder() : null;\n" + " } else {\n" + " $name$Builder_.addAllMessages(other.$name$_);\n" + " }\n" + "}\n"); +} + +void RepeatedImmutableMessageFieldGenerator::GenerateBuildingCode( + io::Printer* printer) const { + // The code below (non-nested builder case) ensures that the result has an + // immutable list. If our list is immutable, we can just reuse it. If not, + // we make it immutable. + PrintNestedBuilderCondition( + printer, + "if ($get_mutable_bit_builder$) {\n" + " $name$_ = java.util.Collections.unmodifiableList($name$_);\n" + " $clear_mutable_bit_builder$;\n" + "}\n" + "result.$name$_ = $name$_;\n", + + "result.$name$_ = $name$Builder_.build();\n"); +} + +void RepeatedImmutableMessageFieldGenerator::GenerateParsingCode( + io::Printer* printer) const { + printer->Print(variables_, + "if (!$get_mutable_bit_parser$) {\n" + " $name$_ = new java.util.ArrayList<$type$>();\n" + " $set_mutable_bit_parser$;\n" + "}\n"); + + if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) { + printer->Print( + variables_, + "$name$_.add(input.readGroup($number$, $type$.$get_parser$,\n" + " extensionRegistry));\n"); + } else { + printer->Print( + variables_, + "$name$_.add(\n" + " input.readMessage($type$.$get_parser$, extensionRegistry));\n"); + } +} + +void RepeatedImmutableMessageFieldGenerator::GenerateParsingDoneCode( + io::Printer* printer) const { + printer->Print( + variables_, + "if ($get_mutable_bit_parser$) {\n" + " $name$_ = java.util.Collections.unmodifiableList($name$_);\n" + "}\n"); +} + +void RepeatedImmutableMessageFieldGenerator::GenerateSerializationCode( + io::Printer* printer) const { + printer->Print(variables_, + "for (int i = 0; i < $name$_.size(); i++) {\n" + " output.write$group_or_message$($number$, $name$_.get(i));\n" + "}\n"); +} + +void RepeatedImmutableMessageFieldGenerator::GenerateSerializedSizeCode( + io::Printer* printer) const { + printer->Print( + variables_, + "for (int i = 0; i < $name$_.size(); i++) {\n" + " size += com.google.protobuf.CodedOutputStream\n" + " .compute$group_or_message$Size($number$, $name$_.get(i));\n" + "}\n"); +} + +void RepeatedImmutableMessageFieldGenerator::GenerateEqualsCode( + io::Printer* printer) const { + printer->Print( + variables_, + "if (!get$capitalized_name$List()\n" + " .equals(other.get$capitalized_name$List())) return false;\n"); +} + +void RepeatedImmutableMessageFieldGenerator::GenerateHashCode( + io::Printer* printer) const { + printer->Print( + variables_, + "if (get$capitalized_name$Count() > 0) {\n" + " hash = (37 * hash) + $constant_name$;\n" + " hash = (53 * hash) + get$capitalized_name$List().hashCode();\n" + "}\n"); +} + +std::string RepeatedImmutableMessageFieldGenerator::GetBoxedType() const { + return name_resolver_->GetImmutableClassName(descriptor_->message_type()); +} + +void RepeatedImmutableMessageFieldGenerator::GenerateKotlinDslMembers( + io::Printer* printer) const { + printer->Print( + variables_, + "/**\n" + " * An uninstantiable, behaviorless type to represent the field in\n" + " * generics.\n" + " */\n" + "@kotlin.OptIn" + "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n" + "public class ${$$kt_capitalized_name$Proxy$}$ private constructor()" + " : com.google.protobuf.kotlin.DslProxy()\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$kt_deprecation$ public val $kt_name$: " + "com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>\n" + " @kotlin.jvm.JvmSynthetic\n" + " get() = com.google.protobuf.kotlin.DslList(\n" + " $kt_dsl_builder$.${$get$capitalized_name$List$}$()\n" + " )\n"); + + WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, + /* builder */ false); + printer->Print(variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"add$kt_capitalized_name$\")\n" + "public fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "add(value: $kt_type$) {\n" + " $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n" + "}"); + + WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, + /* builder */ false); + printer->Print(variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"plusAssign$kt_capitalized_name$\")\n" + "@Suppress(\"NOTHING_TO_INLINE\")\n" + "public inline operator fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "plusAssign(value: $kt_type$) {\n" + " add(value)\n" + "}"); + + WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, + /* builder */ false); + printer->Print(variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"addAll$kt_capitalized_name$\")\n" + "public fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "addAll(values: kotlin.collections.Iterable<$kt_type$>) {\n" + " $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n" + "}"); + + WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, + /* builder */ false); + printer->Print( + variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"plusAssignAll$kt_capitalized_name$\")\n" + "@Suppress(\"NOTHING_TO_INLINE\")\n" + "public inline operator fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "plusAssign(values: kotlin.collections.Iterable<$kt_type$>) {\n" + " addAll(values)\n" + "}"); + + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER, + /* builder */ false); + printer->Print( + variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"set$kt_capitalized_name$\")\n" + "public operator fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "set(index: kotlin.Int, value: $kt_type$) {\n" + " $kt_dsl_builder$.${$set$capitalized_name$$}$(index, value)\n" + "}"); + + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ false); + printer->Print(variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"clear$kt_capitalized_name$\")\n" + "public fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "clear() {\n" + " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n" + "}"); +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_field.h new file mode 100644 index 00000000..2ade2ba8 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_field.h @@ -0,0 +1,179 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_H__ + +#include <map> +#include <string> +#include <compiler/java/java_field.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { +class Context; // context.h +class ClassNameResolver; // name_resolver.h +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +class ImmutableMessageFieldGenerator : public ImmutableFieldGenerator { + public: + explicit ImmutableMessageFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex, + Context* context); + ~ImmutableMessageFieldGenerator(); + + // implements ImmutableFieldGenerator + // --------------------------------------- + int GetNumBitsForMessage() const override; + int GetNumBitsForBuilder() const override; + void GenerateInterfaceMembers(io::Printer* printer) const override; + void GenerateMembers(io::Printer* printer) const override; + void GenerateBuilderMembers(io::Printer* printer) const override; + void GenerateInitializationCode(io::Printer* printer) const override; + void GenerateBuilderClearCode(io::Printer* printer) const override; + void GenerateMergingCode(io::Printer* printer) const override; + void GenerateBuildingCode(io::Printer* printer) const override; + void GenerateParsingCode(io::Printer* printer) const override; + void GenerateParsingDoneCode(io::Printer* printer) const override; + void GenerateSerializationCode(io::Printer* printer) const override; + void GenerateSerializedSizeCode(io::Printer* printer) const override; + void GenerateFieldBuilderInitializationCode( + io::Printer* printer) const override; + void GenerateEqualsCode(io::Printer* printer) const override; + void GenerateHashCode(io::Printer* printer) const override; + void GenerateKotlinDslMembers(io::Printer* printer) const override; + + std::string GetBoxedType() const override; + + protected: + const FieldDescriptor* descriptor_; + std::map<std::string, std::string> variables_; + ClassNameResolver* name_resolver_; + + void PrintNestedBuilderCondition(io::Printer* printer, + const char* regular_case, + const char* nested_builder_case) const; + void PrintNestedBuilderFunction(io::Printer* printer, + const char* method_prototype, + const char* regular_case, + const char* nested_builder_case, + const char* trailing_code) const; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageFieldGenerator); +}; + +class ImmutableMessageOneofFieldGenerator + : public ImmutableMessageFieldGenerator { + public: + ImmutableMessageOneofFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, int builderBitIndex, + Context* context); + ~ImmutableMessageOneofFieldGenerator(); + + void GenerateMembers(io::Printer* printer) const override; + void GenerateBuilderMembers(io::Printer* printer) const override; + void GenerateBuildingCode(io::Printer* printer) const override; + void GenerateMergingCode(io::Printer* printer) const override; + void GenerateParsingCode(io::Printer* printer) const override; + void GenerateSerializationCode(io::Printer* printer) const override; + void GenerateSerializedSizeCode(io::Printer* printer) const override; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageOneofFieldGenerator); +}; + +class RepeatedImmutableMessageFieldGenerator : public ImmutableFieldGenerator { + public: + explicit RepeatedImmutableMessageFieldGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, + int builderBitIndex, Context* context); + ~RepeatedImmutableMessageFieldGenerator() override; + + // implements ImmutableFieldGenerator --------------------------------------- + int GetNumBitsForMessage() const override; + int GetNumBitsForBuilder() const override; + void GenerateInterfaceMembers(io::Printer* printer) const override; + void GenerateMembers(io::Printer* printer) const override; + void GenerateBuilderMembers(io::Printer* printer) const override; + void GenerateInitializationCode(io::Printer* printer) const override; + void GenerateBuilderClearCode(io::Printer* printer) const override; + void GenerateMergingCode(io::Printer* printer) const override; + void GenerateBuildingCode(io::Printer* printer) const override; + void GenerateParsingCode(io::Printer* printer) const override; + void GenerateParsingDoneCode(io::Printer* printer) const override; + void GenerateSerializationCode(io::Printer* printer) const override; + void GenerateSerializedSizeCode(io::Printer* printer) const override; + void GenerateFieldBuilderInitializationCode( + io::Printer* printer) const override; + void GenerateEqualsCode(io::Printer* printer) const override; + void GenerateHashCode(io::Printer* printer) const override; + void GenerateKotlinDslMembers(io::Printer* printer) const override; + + std::string GetBoxedType() const override; + + protected: + const FieldDescriptor* descriptor_; + std::map<std::string, std::string> variables_; + ClassNameResolver* name_resolver_; + + void PrintNestedBuilderCondition(io::Printer* printer, + const char* regular_case, + const char* nested_builder_case) const; + void PrintNestedBuilderFunction(io::Printer* printer, + const char* method_prototype, + const char* regular_case, + const char* nested_builder_case, + const char* trailing_code) const; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableMessageFieldGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_H__ diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_field_lite.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_field_lite.cc new file mode 100644 index 00000000..f3050db3 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_field_lite.cc @@ -0,0 +1,884 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <compiler/java/java_message_field_lite.h> + +#include <cstdint> +#include <map> +#include <string> + +#include <compiler/java/java_context.h> +#include <compiler/java/java_doc_comment.h> +#include <compiler/java/java_helpers.h> +#include <compiler/java/java_name_resolver.h> +#include <io/printer.h> +#include <wire_format.h> +#include <stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +namespace { + +void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex, + int builderBitIndex, const FieldGeneratorInfo* info, + ClassNameResolver* name_resolver, + std::map<std::string, std::string>* variables) { + SetCommonFieldVariables(descriptor, info, variables); + + (*variables)["type"] = + name_resolver->GetImmutableClassName(descriptor->message_type()); + (*variables)["kt_type"] = (*variables)["type"]; + (*variables)["mutable_type"] = + name_resolver->GetMutableClassName(descriptor->message_type()); + (*variables)["group_or_message"] = + (GetType(descriptor) == FieldDescriptor::TYPE_GROUP) ? "Group" + : "Message"; + // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported + // by the proto compiler + (*variables)["deprecation"] = + descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; + (*variables)["kt_deprecation"] = + descriptor->options().deprecated() + ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] + + " is deprecated\") " + : ""; + (*variables)["required"] = descriptor->is_required() ? "true" : "false"; + + if (HasHasbit(descriptor)) { + // For singular messages and builders, one bit is used for the hasField bit. + (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); + + // Note that these have a trailing ";". + (*variables)["set_has_field_bit_message"] = + GenerateSetBit(messageBitIndex) + ";"; + (*variables)["clear_has_field_bit_message"] = + GenerateClearBit(messageBitIndex) + ";"; + + (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex); + } else { + (*variables)["set_has_field_bit_message"] = ""; + (*variables)["clear_has_field_bit_message"] = ""; + + (*variables)["is_field_present_message"] = + (*variables)["name"] + "_ != null"; + } + + (*variables)["get_has_field_bit_from_local"] = + GenerateGetBitFromLocal(builderBitIndex); + (*variables)["set_has_field_bit_to_local"] = + GenerateSetBitToLocal(messageBitIndex); + + // We use `x.getClass()` as a null check because it generates less bytecode + // than an `if (x == null) { throw ... }` statement. + (*variables)["null_check"] = "value.getClass();\n"; +} + +} // namespace + +// =================================================================== + +ImmutableMessageFieldLiteGenerator::ImmutableMessageFieldLiteGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, Context* context) + : descriptor_(descriptor), + messageBitIndex_(messageBitIndex), + name_resolver_(context->GetNameResolver()) { + SetMessageVariables(descriptor, messageBitIndex, 0, + context->GetFieldGeneratorInfo(descriptor), + name_resolver_, &variables_); +} + +ImmutableMessageFieldLiteGenerator::~ImmutableMessageFieldLiteGenerator() {} + +int ImmutableMessageFieldLiteGenerator::GetNumBitsForMessage() const { + // TODO(dweis): We don't need a has bit for messages as they have null + // sentinels and no user should be reflecting on this. We could save some + // bits by setting to 0 and updating the runtimes but this might come at a + // runtime performance cost since we can't memoize has-bit reads. + return HasHasbit(descriptor_) ? 1 : 0; +} + +void ImmutableMessageFieldLiteGenerator::GenerateInterfaceMembers( + io::Printer* printer) const { + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print(variables_, "$deprecation$boolean has$capitalized_name$();\n"); + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n"); +} + +void ImmutableMessageFieldLiteGenerator::GenerateMembers( + io::Printer* printer) const { + + printer->Print(variables_, "private $type$ $name$_;\n"); + PrintExtraFieldInfo(variables_, printer); + + if (HasHasbit(descriptor_)) { + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return $get_has_field_bit_message$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" + " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } else { + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return $name$_ != null;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" + " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } + + // Field.Builder setField(Field value) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void set$capitalized_name$($type$ value) {\n" + " $null_check$" + " $name$_ = value;\n" + " $set_has_field_bit_message$\n" + " }\n"); + + // Field.Builder mergeField(Field value) + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.SuppressWarnings({\"ReferenceEquality\"})\n" + "private void merge$capitalized_name$($type$ value) {\n" + " $null_check$" + " if ($name$_ != null &&\n" + " $name$_ != $type$.getDefaultInstance()) {\n" + " $name$_ =\n" + " $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n" + " } else {\n" + " $name$_ = value;\n" + " }\n" + " $set_has_field_bit_message$\n" + "}\n"); + + // Field.Builder clearField() + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void clear$capitalized_name$() {" + " $name$_ = null;\n" + " $clear_has_field_bit_message$\n" + "}\n"); +} + +void ImmutableMessageFieldLiteGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + // The comments above the methods below are based on a hypothetical + // field of type "Field" called "Field". + + // boolean hasField() + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return instance.has$capitalized_name$();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + // Field getField() + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" + " return instance.get$capitalized_name$();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + // Field.Builder setField(Field value) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder " + "${$set$capitalized_name$$}$($type$ value) {\n" + " copyOnWrite();\n" + " instance.set$capitalized_name$(value);\n" + " return this;\n" + " }\n"); + printer->Annotate("{", "}", descriptor_); + + // Field.Builder setField(Field.Builder builderForValue) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" + " $type$.Builder builderForValue) {\n" + " copyOnWrite();\n" + " instance.set$capitalized_name$(builderForValue.build());\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + // Field.Builder mergeField(Field value) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder " + "${$merge$capitalized_name$$}$($type$ value) {\n" + " copyOnWrite();\n" + " instance.merge$capitalized_name$(value);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + // Field.Builder clearField() + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {" + " copyOnWrite();\n" + " instance.clear$capitalized_name$();\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +void ImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers( + io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$kt_deprecation$public var $kt_name$: $kt_type$\n" + " @JvmName(\"${$get$kt_capitalized_name$$}$\")\n" + " get() = $kt_dsl_builder$.${$get$capitalized_name$$}$()\n" + " @JvmName(\"${$set$kt_capitalized_name$$}$\")\n" + " set(value) {\n" + " $kt_dsl_builder$.${$set$capitalized_name$$}$(value)\n" + " }\n"); + + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ false); + printer->Print(variables_, + "public fun ${$clear$kt_capitalized_name$$}$() {\n" + " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n" + "}\n"); + + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print( + variables_, + "public fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n" + " return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n" + "}\n"); +} + +void ImmutableMessageFieldLiteGenerator::GenerateFieldInfo( + io::Printer* printer, std::vector<uint16_t>* output) const { + WriteIntToUtf16CharSequence(descriptor_->number(), output); + WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_), + output); + if (HasHasbit(descriptor_)) { + WriteIntToUtf16CharSequence(messageBitIndex_, output); + } + printer->Print(variables_, "\"$name$_\",\n"); +} + +void ImmutableMessageFieldLiteGenerator::GenerateInitializationCode( + io::Printer* printer) const {} + +std::string ImmutableMessageFieldLiteGenerator::GetBoxedType() const { + return name_resolver_->GetImmutableClassName(descriptor_->message_type()); +} + +// =================================================================== + +ImmutableMessageOneofFieldLiteGenerator:: + ImmutableMessageOneofFieldLiteGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + Context* context) + : ImmutableMessageFieldLiteGenerator(descriptor, messageBitIndex, context) { + const OneofGeneratorInfo* info = + context->GetOneofGeneratorInfo(descriptor->containing_oneof()); + SetCommonOneofVariables(descriptor, info, &variables_); +} + +ImmutableMessageOneofFieldLiteGenerator:: + ~ImmutableMessageOneofFieldLiteGenerator() {} + +void ImmutableMessageOneofFieldLiteGenerator::GenerateMembers( + io::Printer* printer) const { + PrintExtraFieldInfo(variables_, printer); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return $has_oneof_case_message$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" + " if ($has_oneof_case_message$) {\n" + " return ($type$) $oneof_name$_;\n" + " }\n" + " return $type$.getDefaultInstance();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + // Field.Builder setField(Field value) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void set$capitalized_name$($type$ value) {\n" + " $null_check$" + " $oneof_name$_ = value;\n" + " $set_oneof_case_message$;\n" + "}\n"); + + // Field.Builder mergeField(Field value) + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "private void merge$capitalized_name$($type$ value) {\n" + " $null_check$" + " if ($has_oneof_case_message$ &&\n" + " $oneof_name$_ != $type$.getDefaultInstance()) {\n" + " $oneof_name$_ = $type$.newBuilder(($type$) $oneof_name$_)\n" + " .mergeFrom(value).buildPartial();\n" + " } else {\n" + " $oneof_name$_ = value;\n" + " }\n" + " $set_oneof_case_message$;\n" + "}\n"); + + // Field.Builder clearField() + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void clear$capitalized_name$() {\n" + " if ($has_oneof_case_message$) {\n" + " $clear_oneof_case_message$;\n" + " $oneof_name$_ = null;\n" + " }\n" + "}\n"); +} + +void ImmutableMessageOneofFieldLiteGenerator::GenerateFieldInfo( + io::Printer* printer, std::vector<uint16_t>* output) const { + WriteIntToUtf16CharSequence(descriptor_->number(), output); + WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_), + output); + WriteIntToUtf16CharSequence(descriptor_->containing_oneof()->index(), output); + printer->Print(variables_, "$oneof_stored_type$.class,\n"); +} + +void ImmutableMessageOneofFieldLiteGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + // The comments above the methods below are based on a hypothetical + // field of type "Field" called "Field". + + // boolean hasField() + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return instance.has$capitalized_name$();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + // Field getField() + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" + " return instance.get$capitalized_name$();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + // Field.Builder setField(Field value) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder " + "${$set$capitalized_name$$}$($type$ value) {\n" + " copyOnWrite();\n" + " instance.set$capitalized_name$(value);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + // Field.Builder setField(Field.Builder builderForValue) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" + " $type$.Builder builderForValue) {\n" + " copyOnWrite();\n" + " instance.set$capitalized_name$(builderForValue.build());\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + // Field.Builder mergeField(Field value) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder " + "${$merge$capitalized_name$$}$($type$ value) {\n" + " copyOnWrite();\n" + " instance.merge$capitalized_name$(value);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + // Field.Builder clearField() + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" + " copyOnWrite();\n" + " instance.clear$capitalized_name$();\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +// =================================================================== + +RepeatedImmutableMessageFieldLiteGenerator:: + RepeatedImmutableMessageFieldLiteGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, + Context* context) + : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) { + SetMessageVariables(descriptor, messageBitIndex, 0, + context->GetFieldGeneratorInfo(descriptor), + name_resolver_, &variables_); +} + +RepeatedImmutableMessageFieldLiteGenerator:: + ~RepeatedImmutableMessageFieldLiteGenerator() {} + +int RepeatedImmutableMessageFieldLiteGenerator::GetNumBitsForMessage() const { + return 0; +} + +void RepeatedImmutableMessageFieldLiteGenerator::GenerateInterfaceMembers( + io::Printer* printer) const { + // TODO(jonp): In the future, consider having methods specific to the + // interface so that builders can choose dynamically to either return a + // message or a nested builder, so that asking for the interface doesn't + // cause a message to ever be built. + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$java.util.List<$type$> \n" + " get$capitalized_name$List();\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$$type$ get$capitalized_name$(int index);\n"); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$int get$capitalized_name$Count();\n"); +} + +void RepeatedImmutableMessageFieldLiteGenerator::GenerateMembers( + io::Printer* printer) const { + printer->Print( + variables_, + "private com.google.protobuf.Internal.ProtobufList<$type$> $name$_;\n"); + PrintExtraFieldInfo(variables_, printer); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public java.util.List<$type$> " + "${$get$capitalized_name$List$}$() {\n" + " return $name$_;\n" // note: unmodifiable list + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$public java.util.List<? extends $type$OrBuilder> \n" + " ${$get$capitalized_name$OrBuilderList$}$() {\n" + " return $name$_;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" + " return $name$_.size();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" + " return $name$_.get(index);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public $type$OrBuilder " + "${$get$capitalized_name$OrBuilder$}$(\n" + " int index) {\n" + " return $name$_.get(index);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + printer->Print( + variables_, + "private void ensure$capitalized_name$IsMutable() {\n" + // Use a temporary to avoid a redundant iget-object. + " com.google.protobuf.Internal.ProtobufList<$type$> tmp = $name$_;\n" + " if (!tmp.isModifiable()) {\n" + " $name$_ =\n" + " com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);\n" + " }\n" + "}\n" + "\n"); + + // Builder setRepeatedField(int index, Field value) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void set$capitalized_name$(\n" + " int index, $type$ value) {\n" + " $null_check$" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.set(index, value);\n" + "}\n"); + + // Builder addRepeatedField(Field value) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void add$capitalized_name$($type$ value) {\n" + " $null_check$" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.add(value);\n" + "}\n"); + + // Builder addRepeatedField(int index, Field value) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void add$capitalized_name$(\n" + " int index, $type$ value) {\n" + " $null_check$" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.add(index, value);\n" + "}\n"); + + // Builder addAllRepeatedField(Iterable<Field> values) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void addAll$capitalized_name$(\n" + " java.lang.Iterable<? extends $type$> values) {\n" + " ensure$capitalized_name$IsMutable();\n" + " com.google.protobuf.AbstractMessageLite.addAll(\n" + " values, $name$_);\n" + "}\n"); + + // Builder clearAllRepeatedField() + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void clear$capitalized_name$() {\n" + " $name$_ = emptyProtobufList();\n" + "}\n"); + + // Builder removeRepeatedField(int index) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "private void remove$capitalized_name$(int index) {\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.remove(index);\n" + "}\n"); +} + +void RepeatedImmutableMessageFieldLiteGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + // The comments above the methods below are based on a hypothetical + // repeated field of type "Field" called "RepeatedField". + + // List<Field> getRepeatedFieldList() + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public java.util.List<$type$> " + "${$get$capitalized_name$List$}$() {\n" + " return java.util.Collections.unmodifiableList(\n" + " instance.get$capitalized_name$List());\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + // int getRepeatedFieldCount() + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" + " return instance.get$capitalized_name$Count();\n" + "}"); + printer->Annotate("{", "}", descriptor_); + + // Field getRepeatedField(int index) + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" + " return instance.get$capitalized_name$(index);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + // Builder setRepeatedField(int index, Field value) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" + " int index, $type$ value) {\n" + " copyOnWrite();\n" + " instance.set$capitalized_name$(index, value);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + // Builder setRepeatedField(int index, Field.Builder builderForValue) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" + " int index, $type$.Builder builderForValue) {\n" + " copyOnWrite();\n" + " instance.set$capitalized_name$(index,\n" + " builderForValue.build());\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + // Builder addRepeatedField(Field value) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder " + "${$add$capitalized_name$$}$($type$ value) {\n" + " copyOnWrite();\n" + " instance.add$capitalized_name$(value);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + // Builder addRepeatedField(int index, Field value) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder ${$add$capitalized_name$$}$(\n" + " int index, $type$ value) {\n" + " copyOnWrite();\n" + " instance.add$capitalized_name$(index, value);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + // Builder addRepeatedField(Field.Builder builderForValue) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder ${$add$capitalized_name$$}$(\n" + " $type$.Builder builderForValue) {\n" + " copyOnWrite();\n" + " instance.add$capitalized_name$(builderForValue.build());\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + // Builder addRepeatedField(int index, Field.Builder builderForValue) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder ${$add$capitalized_name$$}$(\n" + " int index, $type$.Builder builderForValue) {\n" + " copyOnWrite();\n" + " instance.add$capitalized_name$(index,\n" + " builderForValue.build());\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + // Builder addAllRepeatedField(Iterable<Field> values) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n" + " java.lang.Iterable<? extends $type$> values) {\n" + " copyOnWrite();\n" + " instance.addAll$capitalized_name$(values);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + // Builder clearAllRepeatedField() + WriteFieldDocComment(printer, descriptor_); + printer->Print( + variables_, + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" + " copyOnWrite();\n" + " instance.clear$capitalized_name$();\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + // Builder removeRepeatedField(int index) + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$deprecation$public Builder " + "${$remove$capitalized_name$$}$(int index) {\n" + " copyOnWrite();\n" + " instance.remove$capitalized_name$(index);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +void RepeatedImmutableMessageFieldLiteGenerator::GenerateFieldInfo( + io::Printer* printer, std::vector<uint16_t>* output) const { + WriteIntToUtf16CharSequence(descriptor_->number(), output); + WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_), + output); + printer->Print(variables_, + "\"$name$_\",\n" + "$type$.class,\n"); +} + +void RepeatedImmutableMessageFieldLiteGenerator::GenerateInitializationCode( + io::Printer* printer) const { + printer->Print(variables_, "$name$_ = emptyProtobufList();\n"); +} + +std::string RepeatedImmutableMessageFieldLiteGenerator::GetBoxedType() const { + return name_resolver_->GetImmutableClassName(descriptor_->message_type()); +} + +void RepeatedImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers( + io::Printer* printer) const { + printer->Print( + variables_, + "/**\n" + " * An uninstantiable, behaviorless type to represent the field in\n" + " * generics.\n" + " */\n" + "@kotlin.OptIn" + "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n" + "public class ${$$kt_capitalized_name$Proxy$}$ private constructor()" + " : com.google.protobuf.kotlin.DslProxy()\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$kt_deprecation$ public val $kt_name$: " + "com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>\n" + " @kotlin.jvm.JvmSynthetic\n" + " get() = com.google.protobuf.kotlin.DslList(\n" + " $kt_dsl_builder$.${$get$capitalized_name$List$}$()\n" + " )\n"); + + WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, + /* builder */ false); + printer->Print(variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"add$kt_capitalized_name$\")\n" + "public fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "add(value: $kt_type$) {\n" + " $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n" + "}"); + + WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, + /* builder */ false); + printer->Print(variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"plusAssign$kt_capitalized_name$\")\n" + "@Suppress(\"NOTHING_TO_INLINE\")\n" + "public inline operator fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "plusAssign(value: $kt_type$) {\n" + " add(value)\n" + "}"); + + WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, + /* builder */ false); + printer->Print(variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"addAll$kt_capitalized_name$\")\n" + "public fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "addAll(values: kotlin.collections.Iterable<$kt_type$>) {\n" + " $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n" + "}"); + + WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, + /* builder */ false); + printer->Print( + variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"plusAssignAll$kt_capitalized_name$\")\n" + "@Suppress(\"NOTHING_TO_INLINE\")\n" + "public inline operator fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "plusAssign(values: kotlin.collections.Iterable<$kt_type$>) {\n" + " addAll(values)\n" + "}"); + + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER, + /* builder */ false); + printer->Print( + variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"set$kt_capitalized_name$\")\n" + "public operator fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "set(index: kotlin.Int, value: $kt_type$) {\n" + " $kt_dsl_builder$.${$set$capitalized_name$$}$(index, value)\n" + "}"); + + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ false); + printer->Print(variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"clear$kt_capitalized_name$\")\n" + "public fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "clear() {\n" + " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n" + "}"); +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_field_lite.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_field_lite.h new file mode 100644 index 00000000..d34e61a5 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_field_lite.h @@ -0,0 +1,140 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_LITE_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_LITE_H__ + +#include <cstdint> +#include <map> +#include <string> + +#include <compiler/java/java_field.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { +class Context; // context.h +class ClassNameResolver; // name_resolver.h +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +class ImmutableMessageFieldLiteGenerator : public ImmutableFieldLiteGenerator { + public: + explicit ImmutableMessageFieldLiteGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + Context* context); + ~ImmutableMessageFieldLiteGenerator(); + + // implements ImmutableFieldLiteGenerator + // ------------------------------------ + int GetNumBitsForMessage() const override; + void GenerateInterfaceMembers(io::Printer* printer) const override; + void GenerateMembers(io::Printer* printer) const override; + void GenerateBuilderMembers(io::Printer* printer) const override; + void GenerateInitializationCode(io::Printer* printer) const override; + void GenerateFieldInfo(io::Printer* printer, + std::vector<uint16_t>* output) const override; + void GenerateKotlinDslMembers(io::Printer* printer) const override; + + std::string GetBoxedType() const override; + + protected: + const FieldDescriptor* descriptor_; + std::map<std::string, std::string> variables_; + const int messageBitIndex_; + ClassNameResolver* name_resolver_; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageFieldLiteGenerator); +}; + +class ImmutableMessageOneofFieldLiteGenerator + : public ImmutableMessageFieldLiteGenerator { + public: + ImmutableMessageOneofFieldLiteGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + Context* context); + ~ImmutableMessageOneofFieldLiteGenerator(); + + void GenerateMembers(io::Printer* printer) const override; + void GenerateBuilderMembers(io::Printer* printer) const override; + void GenerateFieldInfo(io::Printer* printer, + std::vector<uint16_t>* output) const override; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageOneofFieldLiteGenerator); +}; + +class RepeatedImmutableMessageFieldLiteGenerator + : public ImmutableFieldLiteGenerator { + public: + explicit RepeatedImmutableMessageFieldLiteGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, Context* context); + ~RepeatedImmutableMessageFieldLiteGenerator() override; + + // implements ImmutableFieldLiteGenerator ------------------------------------ + int GetNumBitsForMessage() const override; + void GenerateInterfaceMembers(io::Printer* printer) const override; + void GenerateMembers(io::Printer* printer) const override; + void GenerateBuilderMembers(io::Printer* printer) const override; + void GenerateInitializationCode(io::Printer* printer) const override; + void GenerateFieldInfo(io::Printer* printer, + std::vector<uint16_t>* output) const override; + void GenerateKotlinDslMembers(io::Printer* printer) const override; + + std::string GetBoxedType() const override; + + protected: + const FieldDescriptor* descriptor_; + std::map<std::string, std::string> variables_; + ClassNameResolver* name_resolver_; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableMessageFieldLiteGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_FIELD_LITE_H__ diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_lite.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_lite.cc new file mode 100644 index 00000000..a8196c2d --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_lite.cc @@ -0,0 +1,977 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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: dweis@google.com (Daniel Weis) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <compiler/java/java_message_lite.h> + +#include <algorithm> +#include <cstdint> +#include <map> +#include <memory> +#include <vector> + +#include <compiler/java/java_context.h> +#include <compiler/java/java_doc_comment.h> +#include <compiler/java/java_enum_lite.h> +#include <compiler/java/java_extension_lite.h> +#include <compiler/java/java_generator_factory.h> +#include <compiler/java/java_helpers.h> +#include <compiler/java/java_message_builder.h> +#include <compiler/java/java_message_builder_lite.h> +#include <compiler/java/java_name_resolver.h> +#include <descriptor.pb.h> +#include <io/coded_stream.h> +#include <io/printer.h> +#include <wire_format.h> +#include <stubs/strutil.h> +#include <stubs/substitute.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +using internal::WireFormat; +using internal::WireFormatLite; + +// =================================================================== +ImmutableMessageLiteGenerator::ImmutableMessageLiteGenerator( + const Descriptor* descriptor, Context* context) + : MessageGenerator(descriptor), + context_(context), + name_resolver_(context->GetNameResolver()), + field_generators_(descriptor, context_) { + GOOGLE_CHECK(!HasDescriptorMethods(descriptor->file(), context->EnforceLite())) + << "Generator factory error: A lite message generator is used to " + "generate non-lite messages."; + for (int i = 0; i < descriptor_->field_count(); i++) { + if (IsRealOneof(descriptor_->field(i))) { + oneofs_.insert(descriptor_->field(i)->containing_oneof()); + } + } +} + +ImmutableMessageLiteGenerator::~ImmutableMessageLiteGenerator() {} + +void ImmutableMessageLiteGenerator::GenerateStaticVariables( + io::Printer* printer, int* bytecode_estimate) { + // Generate static members for all nested types. + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + // TODO(kenton): Reuse MessageGenerator objects? + ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_) + .GenerateStaticVariables(printer, bytecode_estimate); + } +} + +int ImmutableMessageLiteGenerator::GenerateStaticVariableInitializers( + io::Printer* printer) { + int bytecode_estimate = 0; + // Generate static member initializers for all nested types. + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + // TODO(kenton): Reuse MessageGenerator objects? + bytecode_estimate += + ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_) + .GenerateStaticVariableInitializers(printer); + } + return bytecode_estimate; +} + +// =================================================================== + +void ImmutableMessageLiteGenerator::GenerateInterface(io::Printer* printer) { + MaybePrintGeneratedAnnotation(context_, printer, descriptor_, + /* immutable = */ true, "OrBuilder"); + if (descriptor_->extension_range_count() > 0) { + printer->Print( + "$deprecation$public interface ${$$classname$OrBuilder$}$ extends \n" + " $extra_interfaces$\n" + " com.google.protobuf.GeneratedMessageLite.\n" + " ExtendableMessageOrBuilder<\n" + " $classname$, $classname$.Builder> {\n", + "deprecation", + descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "", + "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), + "classname", descriptor_->name(), "{", "", "}", ""); + } else { + printer->Print( + "$deprecation$public interface ${$$classname$OrBuilder$}$ extends\n" + " $extra_interfaces$\n" + " com.google.protobuf.MessageLiteOrBuilder {\n", + "deprecation", + descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "", + "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), + "classname", descriptor_->name(), "{", "", "}", ""); + } + printer->Annotate("{", "}", descriptor_); + + printer->Indent(); + for (int i = 0; i < descriptor_->field_count(); i++) { + printer->Print("\n"); + field_generators_.get(descriptor_->field(i)) + .GenerateInterfaceMembers(printer); + } + for (auto oneof : oneofs_) { + printer->Print( + "\n" + "public $classname$.$oneof_capitalized_name$Case " + "get$oneof_capitalized_name$Case();\n", + "oneof_capitalized_name", + context_->GetOneofGeneratorInfo(oneof)->capitalized_name, "classname", + context_->GetNameResolver()->GetImmutableClassName(descriptor_)); + } + printer->Outdent(); + + printer->Print("}\n"); +} + +// =================================================================== + +void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { + bool is_own_file = IsOwnFile(descriptor_, /* immutable = */ true); + + std::map<std::string, std::string> variables; + variables["static"] = is_own_file ? " " : " static "; + variables["classname"] = descriptor_->name(); + variables["extra_interfaces"] = ExtraMessageInterfaces(descriptor_); + variables["deprecation"] = + descriptor_->options().deprecated() ? "@java.lang.Deprecated " : ""; + + WriteMessageDocComment(printer, descriptor_); + MaybePrintGeneratedAnnotation(context_, printer, descriptor_, + /* immutable = */ true); + + + // The builder_type stores the super type name of the nested Builder class. + std::string builder_type; + if (descriptor_->extension_range_count() > 0) { + printer->Print( + variables, + "$deprecation$public $static$final class $classname$ extends\n" + " com.google.protobuf.GeneratedMessageLite.ExtendableMessage<\n" + " $classname$, $classname$.Builder> implements\n" + " $extra_interfaces$\n" + " $classname$OrBuilder {\n"); + builder_type = strings::Substitute( + "com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<$0, ?>", + name_resolver_->GetImmutableClassName(descriptor_)); + } else { + printer->Print( + variables, + "$deprecation$public $static$final class $classname$ extends\n" + " com.google.protobuf.GeneratedMessageLite<\n" + " $classname$, $classname$.Builder> implements\n" + " $extra_interfaces$\n" + " $classname$OrBuilder {\n"); + + builder_type = "com.google.protobuf.GeneratedMessageLite.Builder"; + } + printer->Indent(); + + GenerateConstructor(printer); + + // Nested types + for (int i = 0; i < descriptor_->enum_type_count(); i++) { + EnumLiteGenerator(descriptor_->enum_type(i), true, context_) + .Generate(printer); + } + + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + // Don't generate Java classes for map entry messages. + if (IsMapEntry(descriptor_->nested_type(i))) continue; + ImmutableMessageLiteGenerator messageGenerator(descriptor_->nested_type(i), + context_); + messageGenerator.GenerateInterface(printer); + messageGenerator.Generate(printer); + } + + // Integers for bit fields. + int totalBits = 0; + for (int i = 0; i < descriptor_->field_count(); i++) { + totalBits += + field_generators_.get(descriptor_->field(i)).GetNumBitsForMessage(); + } + int totalInts = (totalBits + 31) / 32; + for (int i = 0; i < totalInts; i++) { + printer->Print("private int $bit_field_name$;\n", "bit_field_name", + GetBitFieldName(i)); + } + + // oneof + std::map<std::string, std::string> vars; + for (auto oneof : oneofs_) { + vars["oneof_name"] = context_->GetOneofGeneratorInfo(oneof)->name; + vars["oneof_capitalized_name"] = + context_->GetOneofGeneratorInfo(oneof)->capitalized_name; + vars["oneof_index"] = StrCat((oneof)->index()); + // oneofCase_ and oneof_ + printer->Print(vars, + "private int $oneof_name$Case_ = 0;\n" + "private java.lang.Object $oneof_name$_;\n"); + // OneofCase enum + printer->Print(vars, "public enum $oneof_capitalized_name$Case {\n"); + printer->Indent(); + for (int j = 0; j < (oneof)->field_count(); j++) { + const FieldDescriptor* field = (oneof)->field(j); + printer->Print("$field_name$($field_number$),\n", "field_name", + ToUpper(field->name()), "field_number", + StrCat(field->number())); + } + printer->Print("$cap_oneof_name$_NOT_SET(0);\n", "cap_oneof_name", + ToUpper(vars["oneof_name"])); + printer->Print(vars, + "private final int value;\n" + "private $oneof_capitalized_name$Case(int value) {\n" + " this.value = value;\n" + "}\n"); + printer->Print( + vars, + "/**\n" + " * @deprecated Use {@link #forNumber(int)} instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "public static $oneof_capitalized_name$Case valueOf(int value) {\n" + " return forNumber(value);\n" + "}\n" + "\n" + "public static $oneof_capitalized_name$Case forNumber(int value) {\n" + " switch (value) {\n"); + for (int j = 0; j < (oneof)->field_count(); j++) { + const FieldDescriptor* field = (oneof)->field(j); + printer->Print(" case $field_number$: return $field_name$;\n", + "field_number", StrCat(field->number()), + "field_name", ToUpper(field->name())); + } + printer->Print( + " case 0: return $cap_oneof_name$_NOT_SET;\n" + " default: return null;\n" + " }\n" + "}\n" + // TODO(b/135620659): Rename this to "getFieldNumber" or something to + // disambiguate it from actual proto enums. + "public int getNumber() {\n" + " return this.value;\n" + "}\n", + "cap_oneof_name", ToUpper(vars["oneof_name"])); + printer->Outdent(); + printer->Print("};\n\n"); + // oneofCase() + printer->Print(vars, + "@java.lang.Override\n" + "public $oneof_capitalized_name$Case\n" + "get$oneof_capitalized_name$Case() {\n" + " return $oneof_capitalized_name$Case.forNumber(\n" + " $oneof_name$Case_);\n" + "}\n" + "\n" + "private void clear$oneof_capitalized_name$() {\n" + " $oneof_name$Case_ = 0;\n" + " $oneof_name$_ = null;\n" + "}\n" + "\n"); + } + + // Fields + for (int i = 0; i < descriptor_->field_count(); i++) { + printer->Print("public static final int $constant_name$ = $number$;\n", + "constant_name", FieldConstantName(descriptor_->field(i)), + "number", StrCat(descriptor_->field(i)->number())); + field_generators_.get(descriptor_->field(i)).GenerateMembers(printer); + printer->Print("\n"); + } + + GenerateParseFromMethods(printer); + GenerateBuilder(printer); + + if (HasRequiredFields(descriptor_)) { + // Memoizes whether the protocol buffer is fully initialized (has all + // required fields). 0 means false, 1 means true, and all other values + // mean not yet computed. + printer->Print("private byte memoizedIsInitialized = 2;\n"); + } + + printer->Print( + "@java.lang.Override\n" + "@java.lang.SuppressWarnings({\"unchecked\", \"fallthrough\"})\n" + "protected final java.lang.Object dynamicMethod(\n" + " com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n" + " java.lang.Object arg0, java.lang.Object arg1) {\n" + " switch (method) {\n" + " case NEW_MUTABLE_INSTANCE: {\n" + " return new $classname$();\n" + " }\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + + printer->Indent(); + printer->Indent(); + + printer->Print("case NEW_BUILDER: {\n"); + + printer->Indent(); + GenerateDynamicMethodNewBuilder(printer); + printer->Outdent(); + + printer->Print( + "}\n" + "case BUILD_MESSAGE_INFO: {\n"); + + printer->Indent(); + GenerateDynamicMethodNewBuildMessageInfo(printer); + printer->Outdent(); + + printer->Print( + "}\n" + "// fall through\n" + "case GET_DEFAULT_INSTANCE: {\n" + " return DEFAULT_INSTANCE;\n" + "}\n" + "case GET_PARSER: {\n" + // Generally one would use the lazy initialization holder pattern for + // manipulating static fields but that has exceptional cost on Android as + // it will generate an extra class for every message. Instead, use the + // double-check locking pattern which works just as well. + // + // The "parser" temporary mirrors the "PARSER" field to eliminate a read + // at the final return statement. + " com.google.protobuf.Parser<$classname$> parser = PARSER;\n" + " if (parser == null) {\n" + " synchronized ($classname$.class) {\n" + " parser = PARSER;\n" + " if (parser == null) {\n" + " parser =\n" + " new DefaultInstanceBasedParser<$classname$>(\n" + " DEFAULT_INSTANCE);\n" + " PARSER = parser;\n" + " }\n" + " }\n" + " }\n" + " return parser;\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + + printer->Outdent(); + + if (HasRequiredFields(descriptor_)) { + printer->Print( + "}\n" + "case GET_MEMOIZED_IS_INITIALIZED: {\n" + " return memoizedIsInitialized;\n" + "}\n" + "case SET_MEMOIZED_IS_INITIALIZED: {\n" + " memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);\n" + " return null;\n" + "}\n"); + } else { + printer->Print( + "}\n" + "case GET_MEMOIZED_IS_INITIALIZED: {\n" + " return (byte) 1;\n" + "}\n" + "case SET_MEMOIZED_IS_INITIALIZED: {\n" + " return null;\n" + "}\n"); + } + + printer->Outdent(); + printer->Print( + " }\n" + " throw new UnsupportedOperationException();\n" + "}\n" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + + printer->Print( + "\n" + "// @@protoc_insertion_point(class_scope:$full_name$)\n", + "full_name", descriptor_->full_name()); + + // Carefully initialize the default instance in such a way that it doesn't + // conflict with other initialization. + printer->Print("private static final $classname$ DEFAULT_INSTANCE;\n", + "classname", + name_resolver_->GetImmutableClassName(descriptor_)); + + printer->Print( + "static {\n" + " $classname$ defaultInstance = new $classname$();\n" + " // New instances are implicitly immutable so no need to make\n" + " // immutable.\n" + " DEFAULT_INSTANCE = defaultInstance;\n" + // Register the default instance in a map. This map will be used by + // experimental runtime to lookup default instance given a class instance + // without using Java reflection. + " com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(\n" + " $classname$.class, defaultInstance);\n" + "}\n" + "\n", + "classname", descriptor_->name()); + + printer->Print( + "public static $classname$ getDefaultInstance() {\n" + " return DEFAULT_INSTANCE;\n" + "}\n" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + + // 'of' method for Wrappers + if (IsWrappersProtoFile(descriptor_->file())) { + printer->Print( + "public static $classname$ of($field_type$ value) {\n" + " return newBuilder().setValue(value).build();\n" + "}\n" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_), + "field_type", PrimitiveTypeName(GetJavaType(descriptor_->field(0)))); + } + + GenerateParser(printer); + + // Extensions must be declared after the DEFAULT_INSTANCE is initialized + // because the DEFAULT_INSTANCE is used by the extension to lazily retrieve + // the outer class's FileDescriptor. + for (int i = 0; i < descriptor_->extension_count(); i++) { + ImmutableExtensionLiteGenerator(descriptor_->extension(i), context_) + .Generate(printer); + } + + printer->Outdent(); + printer->Print("}\n\n"); +} + +void ImmutableMessageLiteGenerator::GenerateDynamicMethodNewBuildMessageInfo( + io::Printer* printer) { + printer->Indent(); + + // Collect field info into a sequence of UTF-16 chars. It will be embedded + // as a Java string in the generated code. + std::vector<uint16_t> chars; + + int flags = 0; + if (IsProto2(descriptor_->file())) { + flags |= 0x1; + } + if (descriptor_->options().message_set_wire_format()) { + flags |= 0x2; + } + WriteIntToUtf16CharSequence(flags, &chars); + WriteIntToUtf16CharSequence(descriptor_->field_count(), &chars); + + if (descriptor_->field_count() == 0) { + printer->Print("java.lang.Object[] objects = null;"); + } else { + // A single array of all fields (including oneof, oneofCase, hasBits). + printer->Print("java.lang.Object[] objects = new java.lang.Object[] {\n"); + printer->Indent(); + + // Record the number of oneofs. + WriteIntToUtf16CharSequence(oneofs_.size(), &chars); + for (auto oneof : oneofs_) { + printer->Print( + "\"$oneof_name$_\",\n" + "\"$oneof_name$Case_\",\n", + "oneof_name", context_->GetOneofGeneratorInfo(oneof)->name); + } + + // Integers for bit fields. + int total_bits = 0; + for (int i = 0; i < descriptor_->field_count(); i++) { + total_bits += + field_generators_.get(descriptor_->field(i)).GetNumBitsForMessage(); + } + int total_ints = (total_bits + 31) / 32; + for (int i = 0; i < total_ints; i++) { + printer->Print("\"$bit_field_name$\",\n", "bit_field_name", + GetBitFieldName(i)); + } + WriteIntToUtf16CharSequence(total_ints, &chars); + + int map_count = 0; + int repeated_count = 0; + std::unique_ptr<const FieldDescriptor*[]> sorted_fields( + SortFieldsByNumber(descriptor_)); + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = sorted_fields[i]; + if (field->is_map()) { + map_count++; + } else if (field->is_repeated()) { + repeated_count++; + } + } + + WriteIntToUtf16CharSequence(sorted_fields[0]->number(), &chars); + WriteIntToUtf16CharSequence( + sorted_fields[descriptor_->field_count() - 1]->number(), &chars); + WriteIntToUtf16CharSequence(descriptor_->field_count(), &chars); + WriteIntToUtf16CharSequence(map_count, &chars); + WriteIntToUtf16CharSequence(repeated_count, &chars); + + std::vector<const FieldDescriptor*> fields_for_is_initialized_check; + for (int i = 0; i < descriptor_->field_count(); i++) { + if (descriptor_->field(i)->is_required() || + (GetJavaType(descriptor_->field(i)) == JAVATYPE_MESSAGE && + HasRequiredFields(descriptor_->field(i)->message_type()))) { + fields_for_is_initialized_check.push_back(descriptor_->field(i)); + } + } + WriteIntToUtf16CharSequence(fields_for_is_initialized_check.size(), &chars); + + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = sorted_fields[i]; + field_generators_.get(field).GenerateFieldInfo(printer, &chars); + } + printer->Outdent(); + printer->Print("};\n"); + } + + printer->Print("java.lang.String info =\n"); + std::string line; + for (size_t i = 0; i < chars.size(); i++) { + uint16_t code = chars[i]; + EscapeUtf16ToString(code, &line); + if (line.size() >= 80) { + printer->Print(" \"$string$\" +\n", "string", line); + line.clear(); + } + } + printer->Print(" \"$string$\";\n", "string", line); + + printer->Print("return newMessageInfo(DEFAULT_INSTANCE, info, objects);\n"); + printer->Outdent(); +} + +// =================================================================== + +void ImmutableMessageLiteGenerator::GenerateParseFromMethods( + io::Printer* printer) { + printer->Print( + "public static $classname$ parseFrom(\n" + " java.nio.ByteBuffer data)\n" + " throws com.google.protobuf.InvalidProtocolBufferException {\n" + " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n" + " DEFAULT_INSTANCE, data);\n" + "}\n" + "public static $classname$ parseFrom(\n" + " java.nio.ByteBuffer data,\n" + " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" + " throws com.google.protobuf.InvalidProtocolBufferException {\n" + " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n" + " DEFAULT_INSTANCE, data, extensionRegistry);\n" + "}\n" + "public static $classname$ parseFrom(\n" + " com.google.protobuf.ByteString data)\n" + " throws com.google.protobuf.InvalidProtocolBufferException {\n" + " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n" + " DEFAULT_INSTANCE, data);\n" + "}\n" + "public static $classname$ parseFrom(\n" + " com.google.protobuf.ByteString data,\n" + " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" + " throws com.google.protobuf.InvalidProtocolBufferException {\n" + " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n" + " DEFAULT_INSTANCE, data, extensionRegistry);\n" + "}\n" + "public static $classname$ parseFrom(byte[] data)\n" + " throws com.google.protobuf.InvalidProtocolBufferException {\n" + " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n" + " DEFAULT_INSTANCE, data);\n" + "}\n" + "public static $classname$ parseFrom(\n" + " byte[] data,\n" + " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" + " throws com.google.protobuf.InvalidProtocolBufferException {\n" + " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n" + " DEFAULT_INSTANCE, data, extensionRegistry);\n" + "}\n" + "public static $classname$ parseFrom(java.io.InputStream input)\n" + " throws java.io.IOException {\n" + " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n" + " DEFAULT_INSTANCE, input);\n" + "}\n" + "public static $classname$ parseFrom(\n" + " java.io.InputStream input,\n" + " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" + " throws java.io.IOException {\n" + " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n" + " DEFAULT_INSTANCE, input, extensionRegistry);\n" + "}\n" + "public static $classname$ parseDelimitedFrom(java.io.InputStream " + "input)\n" + " throws java.io.IOException {\n" + " return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n" + "}\n" + "public static $classname$ parseDelimitedFrom(\n" + " java.io.InputStream input,\n" + " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" + " throws java.io.IOException {\n" + " return parseDelimitedFrom(DEFAULT_INSTANCE, input, " + "extensionRegistry);\n" + "}\n" + "public static $classname$ parseFrom(\n" + " com.google.protobuf.CodedInputStream input)\n" + " throws java.io.IOException {\n" + " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n" + " DEFAULT_INSTANCE, input);\n" + "}\n" + "public static $classname$ parseFrom(\n" + " com.google.protobuf.CodedInputStream input,\n" + " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" + " throws java.io.IOException {\n" + " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n" + " DEFAULT_INSTANCE, input, extensionRegistry);\n" + "}\n" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); +} + +// =================================================================== + +void ImmutableMessageLiteGenerator::GenerateBuilder(io::Printer* printer) { + printer->Print( + "public static Builder newBuilder() {\n" + " return (Builder) DEFAULT_INSTANCE.createBuilder();\n" + "}\n" + "public static Builder newBuilder($classname$ prototype) {\n" + " return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);\n" + "}\n" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + + MessageBuilderLiteGenerator builderGenerator(descriptor_, context_); + builderGenerator.Generate(printer); +} + +// =================================================================== + +void ImmutableMessageLiteGenerator::GenerateDynamicMethodNewBuilder( + io::Printer* printer) { + printer->Print("return new Builder();\n"); +} + +// =================================================================== + +void ImmutableMessageLiteGenerator::GenerateExtensionRegistrationCode( + io::Printer* printer) { + for (int i = 0; i < descriptor_->extension_count(); i++) { + ImmutableExtensionLiteGenerator(descriptor_->extension(i), context_) + .GenerateRegistrationCode(printer); + } + + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_) + .GenerateExtensionRegistrationCode(printer); + } +} + +// =================================================================== +void ImmutableMessageLiteGenerator::GenerateConstructor(io::Printer* printer) { + printer->Print("private $classname$() {\n", "classname", descriptor_->name()); + printer->Indent(); + + // Initialize all fields to default. + GenerateInitializers(printer); + + printer->Outdent(); + printer->Print("}\n"); +} + +// =================================================================== +void ImmutableMessageLiteGenerator::GenerateParser(io::Printer* printer) { + printer->Print( + "private static volatile com.google.protobuf.Parser<$classname$> " + "PARSER;\n" + "\n" + "public static com.google.protobuf.Parser<$classname$> parser() {\n" + " return DEFAULT_INSTANCE.getParserForType();\n" + "}\n", + "classname", descriptor_->name()); +} + +// =================================================================== +void ImmutableMessageLiteGenerator::GenerateInitializers(io::Printer* printer) { + for (int i = 0; i < descriptor_->field_count(); i++) { + if (!IsRealOneof(descriptor_->field(i))) { + field_generators_.get(descriptor_->field(i)) + .GenerateInitializationCode(printer); + } + } +} + +void ImmutableMessageLiteGenerator::GenerateKotlinDsl( + io::Printer* printer) const { + printer->Print( + "@kotlin.OptIn" + "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n" + "@com.google.protobuf.kotlin.ProtoDslMarker\n"); + printer->Print( + "public class Dsl private constructor(\n" + " private val _builder: $message$.Builder\n" + ") {\n" + " public companion object {\n" + " @kotlin.jvm.JvmSynthetic\n" + " @kotlin.PublishedApi\n" + " internal fun _create(builder: $message$.Builder): Dsl = " + "Dsl(builder)\n" + " }\n" + "\n" + " @kotlin.jvm.JvmSynthetic\n" + " @kotlin.PublishedApi\n" + " internal fun _build(): $message$ = _builder.build()\n", + "message", name_resolver_->GetClassName(descriptor_, true)); + + printer->Indent(); + + for (int i = 0; i < descriptor_->field_count(); i++) { + printer->Print("\n"); + field_generators_.get(descriptor_->field(i)) + .GenerateKotlinDslMembers(printer); + } + + for (auto oneof : oneofs_) { + printer->Print( + "public val $oneof_name$Case: $message$.$oneof_capitalized_name$Case\n" + " @JvmName(\"get$oneof_capitalized_name$Case\")\n" + " get() = _builder.get$oneof_capitalized_name$Case()\n\n" + "public fun clear$oneof_capitalized_name$() {\n" + " _builder.clear$oneof_capitalized_name$()\n" + "}\n", + "oneof_name", context_->GetOneofGeneratorInfo(oneof)->name, + "oneof_capitalized_name", + context_->GetOneofGeneratorInfo(oneof)->capitalized_name, "message", + name_resolver_->GetClassName(descriptor_, true)); + } + + if (descriptor_->extension_range_count() > 0) { + GenerateKotlinExtensions(printer); + } + + printer->Outdent(); + printer->Print("}\n"); +} + +void ImmutableMessageLiteGenerator::GenerateKotlinMembers( + io::Printer* printer) const { + printer->Print( + "@kotlin.jvm.JvmSynthetic\n" + "public inline fun $camelcase_name$(block: $message_kt$.Dsl.() -> " + "kotlin.Unit): " + "$message$ =\n" + " $message_kt$.Dsl._create($message$.newBuilder()).apply { block() " + "}._build()\n", + "camelcase_name", name_resolver_->GetKotlinFactoryName(descriptor_), + "message_kt", name_resolver_->GetKotlinExtensionsClassName(descriptor_), + "message", name_resolver_->GetClassName(descriptor_, true)); + + printer->Print("public object $name$Kt {\n", "name", descriptor_->name()); + printer->Indent(); + GenerateKotlinDsl(printer); + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + if (IsMapEntry(descriptor_->nested_type(i))) continue; + ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_) + .GenerateKotlinMembers(printer); + } + printer->Outdent(); + printer->Print("}\n"); +} + +void ImmutableMessageLiteGenerator::GenerateTopLevelKotlinMembers( + io::Printer* printer) const { + printer->Print( + "public inline fun $message$.copy(block: $message_kt$.Dsl.() -> " + "kotlin.Unit): " + "$message$ =\n" + " $message_kt$.Dsl._create(this.toBuilder()).apply { block() " + "}._build()\n", + "message", name_resolver_->GetClassName(descriptor_, true), "message_kt", + name_resolver_->GetKotlinExtensionsClassName(descriptor_)); + + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + if (IsMapEntry(descriptor_->nested_type(i))) continue; + ImmutableMessageLiteGenerator(descriptor_->nested_type(i), context_) + .GenerateTopLevelKotlinMembers(printer); + } +} + +void ImmutableMessageLiteGenerator::GenerateKotlinExtensions( + io::Printer* printer) const { + std::string message_name = name_resolver_->GetClassName(descriptor_, true); + + printer->Print( + "@Suppress(\"UNCHECKED_CAST\")\n" + "@kotlin.jvm.JvmSynthetic\n" + "public operator fun <T> get(extension: " + "com.google.protobuf.ExtensionLite<$message$, T>): T {\n" + " return if (extension.isRepeated) {\n" + " get(extension as com.google.protobuf.ExtensionLite<$message$, " + "List<*>>) as T\n" + " } else {\n" + " _builder.getExtension(extension)\n" + " }\n" + "}\n\n", + "message", message_name); + + printer->Print( + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.OptIn" + "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n" + "@kotlin.jvm.JvmName(\"-getRepeatedExtension\")\n" + "public operator fun <E> get(\n" + " extension: com.google.protobuf.ExtensionLite<$message$, List<E>>\n" + "): com.google.protobuf.kotlin.ExtensionList<E, $message$> {\n" + " return com.google.protobuf.kotlin.ExtensionList(extension, " + "_builder.getExtension(extension))\n" + "}\n\n", + "message", message_name); + + printer->Print( + "@kotlin.jvm.JvmSynthetic\n" + "public operator fun contains(extension: " + "com.google.protobuf.ExtensionLite<$message$, *>): " + "Boolean {\n" + " return _builder.hasExtension(extension)\n" + "}\n\n", + "message", message_name); + + printer->Print( + "@kotlin.jvm.JvmSynthetic\n" + "public fun clear(extension: " + "com.google.protobuf.ExtensionLite<$message$, *>) " + "{\n" + " _builder.clearExtension(extension)\n" + "}\n\n", + "message", message_name); + + printer->Print( + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.PublishedApi\n" + "internal fun <T> setExtension(extension: " + "com.google.protobuf.ExtensionLite<$message$, T>, " + "value: T) {\n" + " _builder.setExtension(extension, value)\n" + "}\n\n", + "message", message_name); + + printer->Print( + "@kotlin.jvm.JvmSynthetic\n" + "@Suppress(\"NOTHING_TO_INLINE\")\n" + "public inline operator fun <T : Comparable<T>> set(\n" + " extension: com.google.protobuf.ExtensionLite<$message$, T>,\n" + " value: T\n" + ") {\n" + " setExtension(extension, value)\n" + "}\n\n", + "message", message_name); + + printer->Print( + "@kotlin.jvm.JvmSynthetic\n" + "@Suppress(\"NOTHING_TO_INLINE\")\n" + "public inline operator fun set(\n" + " extension: com.google.protobuf.ExtensionLite<$message$, " + "com.google.protobuf.ByteString>,\n" + " value: com.google.protobuf.ByteString\n" + ") {\n" + " setExtension(extension, value)\n" + "}\n\n", + "message", message_name); + + printer->Print( + "@kotlin.jvm.JvmSynthetic\n" + "@Suppress(\"NOTHING_TO_INLINE\")\n" + "public inline operator fun <T : com.google.protobuf.MessageLite> set(\n" + " extension: com.google.protobuf.ExtensionLite<$message$, T>,\n" + " value: T\n" + ") {\n" + " setExtension(extension, value)\n" + "}\n\n", + "message", message_name); + + printer->Print( + "@kotlin.jvm.JvmSynthetic\n" + "public fun<E> com.google.protobuf.kotlin.ExtensionList<E, " + "$message$>.add(value: E) {\n" + " _builder.addExtension(this.extension, value)\n" + "}\n\n", + "message", message_name); + + printer->Print( + "@kotlin.jvm.JvmSynthetic\n" + "@Suppress(\"NOTHING_TO_INLINE\")\n" + "public inline operator fun <E> " + "com.google.protobuf.kotlin.ExtensionList<E, " + "$message$>.plusAssign" + "(value: E) {\n" + " add(value)\n" + "}\n\n", + "message", message_name); + + printer->Print( + "@kotlin.jvm.JvmSynthetic\n" + "public fun<E> com.google.protobuf.kotlin.ExtensionList<E, " + "$message$>.addAll(values: Iterable<E>) {\n" + " for (value in values) {\n" + " add(value)\n" + " }\n" + "}\n\n", + "message", message_name); + + printer->Print( + "@kotlin.jvm.JvmSynthetic\n" + "@Suppress(\"NOTHING_TO_INLINE\")\n" + "public inline operator fun <E> " + "com.google.protobuf.kotlin.ExtensionList<E, " + "$message$>.plusAssign(values: " + "Iterable<E>) {\n" + " addAll(values)\n" + "}\n\n", + "message", message_name); + + printer->Print( + "@kotlin.jvm.JvmSynthetic\n" + "public operator fun <E> com.google.protobuf.kotlin.ExtensionList<E, " + "$message$>.set(index: Int, value: " + "E) {\n" + " _builder.setExtension(this.extension, index, value)\n" + "}\n\n", + "message", message_name); + + printer->Print( + "@kotlin.jvm.JvmSynthetic\n" + "@Suppress(\"NOTHING_TO_INLINE\")\n" + "public inline fun com.google.protobuf.kotlin.ExtensionList<*, " + "$message$>.clear() {\n" + " clear(extension)\n" + "}\n\n", + "message", message_name); +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_lite.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_lite.h new file mode 100644 index 00000000..02f144bd --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_message_lite.h @@ -0,0 +1,86 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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: dweis@google.com (Daniel Weis) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_LITE_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_LITE_H__ + +#include <map> +#include <string> +#include <compiler/java/java_field.h> +#include <compiler/java/java_message.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +class ImmutableMessageLiteGenerator : public MessageGenerator { + public: + ImmutableMessageLiteGenerator(const Descriptor* descriptor, Context* context); + virtual ~ImmutableMessageLiteGenerator(); + + void Generate(io::Printer* printer) override; + void GenerateInterface(io::Printer* printer) override; + void GenerateExtensionRegistrationCode(io::Printer* printer) override; + void GenerateStaticVariables(io::Printer* printer, + int* bytecode_estimate) override; + int GenerateStaticVariableInitializers(io::Printer* printer) override; + void GenerateKotlinDsl(io::Printer* printer) const override; + void GenerateKotlinMembers(io::Printer* printer) const override; + void GenerateTopLevelKotlinMembers(io::Printer* printer) const override; + + private: + void GenerateParseFromMethods(io::Printer* printer); + + void GenerateBuilder(io::Printer* printer); + void GenerateDynamicMethodNewBuilder(io::Printer* printer); + void GenerateInitializers(io::Printer* printer); + void GenerateParser(io::Printer* printer); + void GenerateConstructor(io::Printer* printer); + void GenerateDynamicMethodNewBuildMessageInfo(io::Printer* printer); + void GenerateKotlinExtensions(io::Printer* printer) const; + + Context* context_; + ClassNameResolver* name_resolver_; + FieldGeneratorMap<ImmutableFieldLiteGenerator> field_generators_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageLiteGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_MESSAGE_LITE_H__ diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_name_resolver.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_name_resolver.cc new file mode 100644 index 00000000..2d753bc5 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_name_resolver.cc @@ -0,0 +1,380 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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. + +#include <compiler/java/java_name_resolver.h> + +#include <map> +#include <string> + +#include <compiler/java/java_helpers.h> +#include <compiler/java/java_names.h> +#include <compiler/code_generator.h> +#include <stubs/substitute.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +namespace { +// A suffix that will be appended to the file's outer class name if the name +// conflicts with some other types defined in the file. +const char* kOuterClassNameSuffix = "OuterClass"; + +// Strip package name from a descriptor's full name. +// For example: +// Full name : foo.Bar.Baz +// Package name: foo +// After strip : Bar.Baz +std::string StripPackageName(const std::string& full_name, + const FileDescriptor* file) { + if (file->package().empty()) { + return full_name; + } else { + // Strip package name + return full_name.substr(file->package().size() + 1); + } +} + +// Get the name of a message's Java class without package name prefix. +std::string ClassNameWithoutPackage(const Descriptor* descriptor, + bool immutable) { + return StripPackageName(descriptor->full_name(), descriptor->file()); +} + +std::string ClassNameWithoutPackageKotlin(const Descriptor* descriptor) { + std::string result = descriptor->name(); + const Descriptor* temp = descriptor->containing_type(); + + while (temp) { + result = temp->name() + "Kt." + result; + temp = temp->containing_type(); + } + return result; +} + +// Get the name of an enum's Java class without package name prefix. +std::string ClassNameWithoutPackage(const EnumDescriptor* descriptor, + bool immutable) { + // Doesn't append "Mutable" for enum type's name. + const Descriptor* message_descriptor = descriptor->containing_type(); + if (message_descriptor == NULL) { + return descriptor->name(); + } else { + return ClassNameWithoutPackage(message_descriptor, immutable) + "." + + descriptor->name(); + } +} + +// Get the name of a service's Java class without package name prefix. +std::string ClassNameWithoutPackage(const ServiceDescriptor* descriptor, + bool immutable) { + std::string full_name = + StripPackageName(descriptor->full_name(), descriptor->file()); + // We don't allow nested service definitions. + GOOGLE_CHECK(full_name.find('.') == std::string::npos); + return full_name; +} + +// Return true if a and b are equals (case insensitive). +NameEquality CheckNameEquality(const std::string& a, const std::string& b) { + if (ToUpper(a) == ToUpper(b)) { + if (a == b) { + return NameEquality::EXACT_EQUAL; + } + return NameEquality::EQUAL_IGNORE_CASE; + } + return NameEquality::NO_MATCH; +} + +// Check whether a given message or its nested types has the given class name. +bool MessageHasConflictingClassName(const Descriptor* message, + const std::string& classname, + NameEquality equality_mode) { + if (CheckNameEquality(message->name(), classname) == equality_mode) { + return true; + } + for (int i = 0; i < message->nested_type_count(); ++i) { + if (MessageHasConflictingClassName(message->nested_type(i), classname, + equality_mode)) { + return true; + } + } + for (int i = 0; i < message->enum_type_count(); ++i) { + if (CheckNameEquality(message->enum_type(i)->name(), classname) == + equality_mode) { + return true; + } + } + return false; +} + +} // namespace + +ClassNameResolver::ClassNameResolver() {} + +ClassNameResolver::~ClassNameResolver() {} + +std::string ClassNameResolver::GetFileDefaultImmutableClassName( + const FileDescriptor* file) { + std::string basename; + std::string::size_type last_slash = file->name().find_last_of('/'); + if (last_slash == std::string::npos) { + basename = file->name(); + } else { + basename = file->name().substr(last_slash + 1); + } + return UnderscoresToCamelCase(StripProto(basename), true); +} + +std::string ClassNameResolver::GetFileImmutableClassName( + const FileDescriptor* file) { + std::string& class_name = file_immutable_outer_class_names_[file]; + if (class_name.empty()) { + if (file->options().has_java_outer_classname()) { + class_name = file->options().java_outer_classname(); + } else { + class_name = GetFileDefaultImmutableClassName(file); + if (HasConflictingClassName(file, class_name, + NameEquality::EXACT_EQUAL)) { + class_name += kOuterClassNameSuffix; + } + } + } + return class_name; +} + +std::string ClassNameResolver::GetFileClassName(const FileDescriptor* file, + bool immutable) { + return GetFileClassName(file, immutable, false); +} + +std::string ClassNameResolver::GetFileClassName(const FileDescriptor* file, + bool immutable, bool kotlin) { + if (kotlin) { + return GetFileImmutableClassName(file) + "Kt"; + } else if (immutable) { + return GetFileImmutableClassName(file); + } else { + return "Mutable" + GetFileImmutableClassName(file); + } +} + +// Check whether there is any type defined in the proto file that has +// the given class name. +bool ClassNameResolver::HasConflictingClassName(const FileDescriptor* file, + const std::string& classname, + NameEquality equality_mode) { + for (int i = 0; i < file->enum_type_count(); i++) { + if (CheckNameEquality(file->enum_type(i)->name(), classname) == + equality_mode) { + return true; + } + } + for (int i = 0; i < file->service_count(); i++) { + if (CheckNameEquality(file->service(i)->name(), classname) == + equality_mode) { + return true; + } + } + for (int i = 0; i < file->message_type_count(); i++) { + if (MessageHasConflictingClassName(file->message_type(i), classname, + equality_mode)) { + return true; + } + } + return false; +} + +std::string ClassNameResolver::GetDescriptorClassName( + const FileDescriptor* descriptor) { + return GetFileImmutableClassName(descriptor); +} + +std::string ClassNameResolver::GetClassName(const FileDescriptor* descriptor, + bool immutable) { + return GetClassName(descriptor, immutable, false); +} + +std::string ClassNameResolver::GetClassName(const FileDescriptor* descriptor, + bool immutable, bool kotlin) { + std::string result = FileJavaPackage(descriptor, immutable); + if (!result.empty()) result += '.'; + result += GetFileClassName(descriptor, immutable, kotlin); + return result; +} + +// Get the full name of a Java class by prepending the Java package name +// or outer class name. +std::string ClassNameResolver::GetClassFullName( + const std::string& name_without_package, const FileDescriptor* file, + bool immutable, bool is_own_file) { + return GetClassFullName(name_without_package, file, immutable, is_own_file, + false); +} + +std::string ClassNameResolver::GetClassFullName( + const std::string& name_without_package, const FileDescriptor* file, + bool immutable, bool is_own_file, bool kotlin) { + std::string result; + if (is_own_file) { + result = FileJavaPackage(file, immutable); + } else { + result = GetClassName(file, immutable, kotlin); + } + if (!result.empty()) { + result += '.'; + } + result += name_without_package; + if (kotlin) result += "Kt"; + return result; +} + +std::string ClassNameResolver::GetClassName(const Descriptor* descriptor, + bool immutable) { + return GetClassName(descriptor, immutable, false); +} + +std::string ClassNameResolver::GetClassName(const Descriptor* descriptor, + bool immutable, bool kotlin) { + return GetClassFullName( + ClassNameWithoutPackage(descriptor, immutable), descriptor->file(), + immutable, MultipleJavaFiles(descriptor->file(), immutable), kotlin); +} + +std::string ClassNameResolver::GetClassName(const EnumDescriptor* descriptor, + bool immutable) { + return GetClassName(descriptor, immutable, false); +} + +std::string ClassNameResolver::GetClassName(const EnumDescriptor* descriptor, + bool immutable, bool kotlin) { + return GetClassFullName( + ClassNameWithoutPackage(descriptor, immutable), descriptor->file(), + immutable, MultipleJavaFiles(descriptor->file(), immutable), kotlin); +} + +std::string ClassNameResolver::GetClassName(const ServiceDescriptor* descriptor, + bool immutable) { + return GetClassName(descriptor, immutable, false); +} + +std::string ClassNameResolver::GetClassName(const ServiceDescriptor* descriptor, + bool immutable, bool kotlin) { + return GetClassFullName(ClassNameWithoutPackage(descriptor, immutable), + descriptor->file(), immutable, + IsOwnFile(descriptor, immutable), kotlin); +} + +// Get the Java Class style full name of a message. +std::string ClassNameResolver::GetJavaClassFullName( + const std::string& name_without_package, const FileDescriptor* file, + bool immutable) { + return GetJavaClassFullName(name_without_package, file, immutable, false); +} + +std::string ClassNameResolver::GetJavaClassFullName( + const std::string& name_without_package, const FileDescriptor* file, + bool immutable, bool kotlin) { + std::string result; + if (MultipleJavaFiles(file, immutable)) { + result = FileJavaPackage(file, immutable); + if (!result.empty()) result += '.'; + } else { + result = GetClassName(file, immutable, kotlin); + if (!result.empty()) result += '$'; + } + result += StringReplace(name_without_package, ".", "$", true); + return result; +} + +std::string ClassNameResolver::GetExtensionIdentifierName( + const FieldDescriptor* descriptor, bool immutable) { + return GetExtensionIdentifierName(descriptor, immutable, false); +} + +std::string ClassNameResolver::GetExtensionIdentifierName( + const FieldDescriptor* descriptor, bool immutable, bool kotlin) { + return GetClassName(descriptor->containing_type(), immutable, kotlin) + "." + + descriptor->name(); +} + +std::string ClassNameResolver::GetKotlinFactoryName( + const Descriptor* descriptor) { + std::string name = ToCamelCase(descriptor->name(), /* lower_first = */ true); + return IsForbiddenKotlin(name) ? name + "_" : name; +} + +std::string ClassNameResolver::GetJavaImmutableClassName( + const Descriptor* descriptor) { + return GetJavaClassFullName(ClassNameWithoutPackage(descriptor, true), + descriptor->file(), true); +} + +std::string ClassNameResolver::GetJavaImmutableClassName( + const EnumDescriptor* descriptor) { + return GetJavaClassFullName(ClassNameWithoutPackage(descriptor, true), + descriptor->file(), true); +} + +std::string ClassNameResolver::GetKotlinExtensionsClassName( + const Descriptor* descriptor) { + return GetClassFullName(ClassNameWithoutPackageKotlin(descriptor), + descriptor->file(), true, true, true); +} + +std::string ClassNameResolver::GetJavaMutableClassName( + const Descriptor* descriptor) { + return GetJavaClassFullName(ClassNameWithoutPackage(descriptor, false), + descriptor->file(), false); +} + +std::string ClassNameResolver::GetJavaMutableClassName( + const EnumDescriptor* descriptor) { + return GetJavaClassFullName(ClassNameWithoutPackage(descriptor, false), + descriptor->file(), false); +} + +std::string ClassNameResolver::GetDowngradedFileClassName( + const FileDescriptor* file) { + return "Downgraded" + GetFileClassName(file, false); +} + +std::string ClassNameResolver::GetDowngradedClassName( + const Descriptor* descriptor) { + return FileJavaPackage(descriptor->file()) + "." + + GetDowngradedFileClassName(descriptor->file()) + "." + + ClassNameWithoutPackage(descriptor, false); +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_name_resolver.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_name_resolver.h new file mode 100644 index 00000000..4d5a9bf6 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_name_resolver.h @@ -0,0 +1,153 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_NAME_RESOLVER_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_NAME_RESOLVER_H__ + +#include <map> +#include <string> + +#include <stubs/common.h> + +namespace google { +namespace protobuf { +class Descriptor; +class EnumDescriptor; +class FieldDescriptor; +class FileDescriptor; +class ServiceDescriptor; + +namespace compiler { +namespace java { + +// Indicates how closely the two class names match. +enum NameEquality { NO_MATCH, EXACT_EQUAL, EQUAL_IGNORE_CASE }; + +// Used to get the Java class related names for a given descriptor. It caches +// the results to avoid redundant calculation across multiple name queries. +// Thread-safety note: This class is *not* thread-safe. +class ClassNameResolver { + public: + ClassNameResolver(); + ~ClassNameResolver(); + + // Gets the unqualified outer class name for the file. + std::string GetFileClassName(const FileDescriptor* file, bool immutable); + std::string GetFileClassName(const FileDescriptor* file, bool immutable, + bool kotlin); + // Gets the unqualified immutable outer class name of a file. + std::string GetFileImmutableClassName(const FileDescriptor* file); + // Gets the unqualified default immutable outer class name of a file + // (converted from the proto file's name). + std::string GetFileDefaultImmutableClassName(const FileDescriptor* file); + + // Check whether there is any type defined in the proto file that has + // the given class name. + bool HasConflictingClassName(const FileDescriptor* file, + const std::string& classname, + NameEquality equality_mode); + + // Gets the name of the outer class that holds descriptor information. + // Descriptors are shared between immutable messages and mutable messages. + // Since both of them are generated optionally, the descriptors need to be + // put in another common place. + std::string GetDescriptorClassName(const FileDescriptor* file); + + // Gets the fully-qualified class name corresponding to the given descriptor. + std::string GetClassName(const Descriptor* descriptor, bool immutable); + std::string GetClassName(const Descriptor* descriptor, bool immutable, + bool kotlin); + std::string GetClassName(const EnumDescriptor* descriptor, bool immutable); + std::string GetClassName(const EnumDescriptor* descriptor, bool immutable, + bool kotlin); + std::string GetClassName(const ServiceDescriptor* descriptor, bool immutable); + std::string GetClassName(const ServiceDescriptor* descriptor, bool immutable, + bool kotlin); + std::string GetClassName(const FileDescriptor* descriptor, bool immutable); + std::string GetClassName(const FileDescriptor* descriptor, bool immutable, + bool kotlin); + + template <class DescriptorType> + std::string GetImmutableClassName(const DescriptorType* descriptor) { + return GetClassName(descriptor, true); + } + template <class DescriptorType> + std::string GetMutableClassName(const DescriptorType* descriptor) { + return GetClassName(descriptor, false); + } + + // Gets the fully qualified name of an extension identifier. + std::string GetExtensionIdentifierName(const FieldDescriptor* descriptor, + bool immutable); + std::string GetExtensionIdentifierName(const FieldDescriptor* descriptor, + bool immutable, bool kotlin); + + // Gets the fully qualified name for generated classes in Java convention. + // Nested classes will be separated using '$' instead of '.' + // For example: + // com.package.OuterClass$OuterMessage$InnerMessage + std::string GetJavaImmutableClassName(const Descriptor* descriptor); + std::string GetJavaImmutableClassName(const EnumDescriptor* descriptor); + std::string GetKotlinFactoryName(const Descriptor* descriptor); + std::string GetKotlinExtensionsClassName(const Descriptor* descriptor); + std::string GetJavaMutableClassName(const Descriptor* descriptor); + std::string GetJavaMutableClassName(const EnumDescriptor* descriptor); + // Gets the outer class and the actual class for downgraded mutable messages. + std::string GetDowngradedFileClassName(const FileDescriptor* file); + std::string GetDowngradedClassName(const Descriptor* descriptor); + + private: + // Get the full name of a Java class by prepending the Java package name + // or outer class name. + std::string GetClassFullName(const std::string& name_without_package, + const FileDescriptor* file, bool immutable, + bool is_own_file); + std::string GetClassFullName(const std::string& name_without_package, + const FileDescriptor* file, bool immutable, + bool is_own_file, bool kotlin); + // Get the Java Class style full name of a message. + std::string GetJavaClassFullName(const std::string& name_without_package, + const FileDescriptor* file, bool immutable); + std::string GetJavaClassFullName(const std::string& name_without_package, + const FileDescriptor* file, bool immutable, + bool kotlin); + // Caches the result to provide better performance. + std::map<const FileDescriptor*, std::string> + file_immutable_outer_class_names_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ClassNameResolver); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_NAME_RESOLVER_H__ diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_names.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_names.h new file mode 100644 index 00000000..313ace4f --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_names.h @@ -0,0 +1,100 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// Provides a mechanism for mapping a descriptor to the +// fully-qualified name of the corresponding Java class. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_NAMES_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_NAMES_H__ + +#include <string> + +namespace google { +namespace protobuf { + +class Descriptor; +class EnumDescriptor; +class FileDescriptor; +class FieldDescriptor; +class ServiceDescriptor; + +namespace compiler { +namespace java { + +// Requires: +// descriptor != NULL +// +// Returns: +// The fully-qualified Java class name. +std::string ClassName(const Descriptor* descriptor); + +// Requires: +// descriptor != NULL +// +// Returns: +// The fully-qualified Java class name. +std::string ClassName(const EnumDescriptor* descriptor); + +// Requires: +// descriptor != NULL +// +// Returns: +// The fully-qualified Java class name. +std::string ClassName(const FileDescriptor* descriptor); + +// Requires: +// descriptor != NULL +// +// Returns: +// The fully-qualified Java class name. +std::string ClassName(const ServiceDescriptor* descriptor); + +// Requires: +// descriptor != NULL +// +// Returns: +// Java package name. +std::string FileJavaPackage(const FileDescriptor* descriptor); + +// Requires: +// descriptor != NULL +// Returns: +// Capitalized camel case name field name. +std::string CapitalizedFieldName(const FieldDescriptor* descriptor); + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_NAMES_H__ diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_options.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_options.h new file mode 100644 index 00000000..6c29be15 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_options.h @@ -0,0 +1,73 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_OPTIONS_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_OPTIONS_H__ + +#include <string> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +// Generator options +struct Options { + Options() + : generate_immutable_code(false), + generate_mutable_code(false), + generate_shared_code(false), + enforce_lite(false), + annotate_code(false) { + } + + bool generate_immutable_code; + bool generate_mutable_code; + bool generate_shared_code; + // When set, the protoc will generate the current files and all the transitive + // dependencies as lite runtime. + bool enforce_lite; + // If true, we should build .meta files and emit @Generated annotations into + // generated code. + bool annotate_code; + // Name of a file where we will write a list of generated .meta file names, + // one per line. + std::string annotation_list_file; + // Name of a file where we will write a list of generated file names, one + // per line. + std::string output_list_file; +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_OPTIONS_H__ diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_plugin_unittest.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_plugin_unittest.cc new file mode 100644 index 00000000..22ae3f24 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_plugin_unittest.cc @@ -0,0 +1,119 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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 <memory> + +#include <testing/file.h> +#include <testing/file.h> +#include <compiler/java/java_generator.h> +#include <compiler/command_line_interface.h> +#include <io/printer.h> +#include <io/zero_copy_stream.h> +#include <testing/googletest.h> +#include <gtest/gtest.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { +namespace { + +class TestGenerator : public CodeGenerator { + public: + TestGenerator() {} + ~TestGenerator() {} + + virtual bool Generate(const FileDescriptor* file, + const std::string& parameter, GeneratorContext* context, + std::string* error) const { + std::string filename = "Test.java"; + TryInsert(filename, "outer_class_scope", context); + TryInsert(filename, "class_scope:foo.Bar", context); + TryInsert(filename, "class_scope:foo.Bar.Baz", context); + TryInsert(filename, "builder_scope:foo.Bar", context); + TryInsert(filename, "builder_scope:foo.Bar.Baz", context); + TryInsert(filename, "enum_scope:foo.Qux", context); + return true; + } + + void TryInsert(const std::string& filename, + const std::string& insertion_point, + GeneratorContext* context) const { + std::unique_ptr<io::ZeroCopyOutputStream> output( + context->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) { + GOOGLE_CHECK_OK(File::SetContents(TestTempDir() + "/test.proto", + "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", + true)); + + CommandLineInterface cli; + cli.SetInputsAreProtoPathRelative(true); + + JavaGenerator java_generator; + TestGenerator test_generator; + cli.RegisterGenerator("--java_out", &java_generator, ""); + cli.RegisterGenerator("--test_out", &test_generator, ""); + + std::string proto_path = "-I" + TestTempDir(); + std::string java_out = "--java_out=" + TestTempDir(); + std::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 diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_primitive_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_primitive_field.cc new file mode 100644 index 00000000..23d00b28 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_primitive_field.cc @@ -0,0 +1,1111 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <compiler/java/java_primitive_field.h> + +#include <cstdint> +#include <map> +#include <string> + +#include <stubs/logging.h> +#include <stubs/common.h> +#include <compiler/java/java_context.h> +#include <compiler/java/java_doc_comment.h> +#include <compiler/java/java_helpers.h> +#include <compiler/java/java_name_resolver.h> +#include <io/printer.h> +#include <wire_format.h> +#include <stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +using internal::WireFormat; + +namespace { + +void SetPrimitiveVariables(const FieldDescriptor* descriptor, + int messageBitIndex, int builderBitIndex, + const FieldGeneratorInfo* info, + ClassNameResolver* name_resolver, + std::map<std::string, std::string>* variables) { + SetCommonFieldVariables(descriptor, info, variables); + JavaType javaType = GetJavaType(descriptor); + + (*variables)["type"] = PrimitiveTypeName(javaType); + (*variables)["boxed_type"] = BoxedPrimitiveTypeName(javaType); + (*variables)["kt_type"] = KotlinTypeName(javaType); + (*variables)["field_type"] = (*variables)["type"]; + + if (javaType == JAVATYPE_BOOLEAN || javaType == JAVATYPE_DOUBLE || + javaType == JAVATYPE_FLOAT || javaType == JAVATYPE_INT || + javaType == JAVATYPE_LONG) { + std::string capitalized_type = UnderscoresToCamelCase( + PrimitiveTypeName(javaType), /*cap_first_letter=*/true); + (*variables)["field_list_type"] = + "com.google.protobuf.Internal." + capitalized_type + "List"; + (*variables)["empty_list"] = "empty" + capitalized_type + "List()"; + (*variables)["create_list"] = "new" + capitalized_type + "List()"; + (*variables)["mutable_copy_list"] = + "mutableCopy(" + (*variables)["name"] + "_)"; + (*variables)["name_make_immutable"] = + (*variables)["name"] + "_.makeImmutable()"; + (*variables)["repeated_get"] = + (*variables)["name"] + "_.get" + capitalized_type; + (*variables)["repeated_add"] = + (*variables)["name"] + "_.add" + capitalized_type; + (*variables)["repeated_set"] = + (*variables)["name"] + "_.set" + capitalized_type; + } else { + (*variables)["field_list_type"] = + "java.util.List<" + (*variables)["boxed_type"] + ">"; + (*variables)["create_list"] = + "new java.util.ArrayList<" + (*variables)["boxed_type"] + ">()"; + (*variables)["mutable_copy_list"] = "new java.util.ArrayList<" + + (*variables)["boxed_type"] + ">(" + + (*variables)["name"] + "_)"; + (*variables)["empty_list"] = "java.util.Collections.emptyList()"; + (*variables)["name_make_immutable"] = + (*variables)["name"] + "_ = java.util.Collections.unmodifiableList(" + + (*variables)["name"] + "_)"; + (*variables)["repeated_get"] = (*variables)["name"] + "_.get"; + (*variables)["repeated_add"] = (*variables)["name"] + "_.add"; + (*variables)["repeated_set"] = (*variables)["name"] + "_.set"; + } + + (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver); + (*variables)["default_init"] = + IsDefaultValueJavaDefault(descriptor) + ? "" + : ("= " + ImmutableDefaultValue(descriptor, name_resolver)); + (*variables)["capitalized_type"] = + GetCapitalizedType(descriptor, /* immutable = */ true); + (*variables)["tag"] = + StrCat(static_cast<int32_t>(WireFormat::MakeTag(descriptor))); + (*variables)["tag_size"] = StrCat( + WireFormat::TagSize(descriptor->number(), GetType(descriptor))); + if (IsReferenceType(GetJavaType(descriptor))) { + (*variables)["null_check"] = + " if (value == null) {\n" + " throw new NullPointerException();\n" + " }\n"; + } else { + (*variables)["null_check"] = ""; + } + // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported + // by the proto compiler + (*variables)["deprecation"] = + descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; + (*variables)["kt_deprecation"] = + descriptor->options().deprecated() + ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] + + " is deprecated\") " + : ""; + int fixed_size = FixedSize(GetType(descriptor)); + if (fixed_size != -1) { + (*variables)["fixed_size"] = StrCat(fixed_size); + } + (*variables)["on_changed"] = "onChanged();"; + + if (HasHasbit(descriptor)) { + // For singular messages and builders, one bit is used for the hasField bit. + (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); + (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex); + + // Note that these have a trailing ";". + (*variables)["set_has_field_bit_message"] = + GenerateSetBit(messageBitIndex) + ";"; + (*variables)["set_has_field_bit_builder"] = + GenerateSetBit(builderBitIndex) + ";"; + (*variables)["clear_has_field_bit_builder"] = + GenerateClearBit(builderBitIndex) + ";"; + + (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex); + } else { + (*variables)["set_has_field_bit_message"] = ""; + (*variables)["set_has_field_bit_builder"] = ""; + (*variables)["clear_has_field_bit_builder"] = ""; + + switch (descriptor->type()) { + case FieldDescriptor::TYPE_BYTES: + (*variables)["is_field_present_message"] = + "!" + (*variables)["name"] + "_.isEmpty()"; + break; + case FieldDescriptor::TYPE_FLOAT: + (*variables)["is_field_present_message"] = + "java.lang.Float.floatToRawIntBits(" + (*variables)["name"] + + "_) != 0"; + break; + case FieldDescriptor::TYPE_DOUBLE: + (*variables)["is_field_present_message"] = + "java.lang.Double.doubleToRawLongBits(" + (*variables)["name"] + + "_) != 0"; + break; + default: + (*variables)["is_field_present_message"] = + (*variables)["name"] + "_ != " + (*variables)["default"]; + break; + } + } + + // For repeated builders, one bit is used for whether the array is immutable. + (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex); + (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex); + (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex); + + // For repeated fields, one bit is used for whether the array is immutable + // in the parsing constructor. + (*variables)["get_mutable_bit_parser"] = + GenerateGetBitMutableLocal(builderBitIndex); + (*variables)["set_mutable_bit_parser"] = + GenerateSetBitMutableLocal(builderBitIndex); + + (*variables)["get_has_field_bit_from_local"] = + GenerateGetBitFromLocal(builderBitIndex); + (*variables)["set_has_field_bit_to_local"] = + GenerateSetBitToLocal(messageBitIndex); +} + +} // namespace + +// =================================================================== + +ImmutablePrimitiveFieldGenerator::ImmutablePrimitiveFieldGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, + Context* context) + : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) { + SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex, + context->GetFieldGeneratorInfo(descriptor), + name_resolver_, &variables_); +} + +ImmutablePrimitiveFieldGenerator::~ImmutablePrimitiveFieldGenerator() {} + +int ImmutablePrimitiveFieldGenerator::GetNumBitsForMessage() const { + return HasHasbit(descriptor_) ? 1 : 0; +} + +int ImmutablePrimitiveFieldGenerator::GetNumBitsForBuilder() const { + return GetNumBitsForMessage(); +} + +void ImmutablePrimitiveFieldGenerator::GenerateInterfaceMembers( + io::Printer* printer) const { + if (HasHazzer(descriptor_)) { + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print(variables_, + "$deprecation$boolean has$capitalized_name$();\n"); + } + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n"); +} + +void ImmutablePrimitiveFieldGenerator::GenerateMembers( + io::Printer* printer) const { + printer->Print(variables_, "private $field_type$ $name$_;\n"); + PrintExtraFieldInfo(variables_, printer); + if (HasHazzer(descriptor_)) { + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return $get_has_field_bit_message$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } + + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" + " return $name$_;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +void ImmutablePrimitiveFieldGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + printer->Print(variables_, "private $field_type$ $name$_ $default_init$;\n"); + + if (HasHazzer(descriptor_)) { + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return $get_has_field_bit_builder$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } + + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" + " return $name$_;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldAccessorDocComment(printer, descriptor_, SETTER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder " + "${$set$capitalized_name$$}$($type$ value) {\n" + "$null_check$" + " $set_has_field_bit_builder$\n" + " $name$_ = value;\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ true); + printer->Print( + variables_, + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" + " $clear_has_field_bit_builder$\n"); + printer->Annotate("{", "}", descriptor_); + JavaType type = GetJavaType(descriptor_); + if (type == JAVATYPE_STRING || type == JAVATYPE_BYTES) { + // The default value is not a simple literal so we want to avoid executing + // it multiple times. Instead, get the default out of the default instance. + printer->Print( + variables_, + " $name$_ = getDefaultInstance().get$capitalized_name$();\n"); + } else { + printer->Print(variables_, " $name$_ = $default$;\n"); + } + printer->Print(variables_, + " $on_changed$\n" + " return this;\n" + "}\n"); +} + +void ImmutablePrimitiveFieldGenerator::GenerateKotlinDslMembers( + io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$kt_deprecation$public var $kt_name$: $kt_type$\n" + " @JvmName(\"${$get$kt_capitalized_name$$}$\")\n" + " get() = $kt_dsl_builder$.${$get$capitalized_name$$}$()\n" + " @JvmName(\"${$set$kt_capitalized_name$$}$\")\n" + " set(value) {\n" + " $kt_dsl_builder$.${$set$capitalized_name$$}$(value)\n" + " }\n"); + + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ false); + printer->Print(variables_, + "public fun ${$clear$kt_capitalized_name$$}$() {\n" + " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n" + "}\n"); + + if (HasHazzer(descriptor_)) { + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print( + variables_, + "public fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n" + " return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n" + "}\n"); + } +} + +void ImmutablePrimitiveFieldGenerator::GenerateFieldBuilderInitializationCode( + io::Printer* printer) const { + // noop for primitives +} + +void ImmutablePrimitiveFieldGenerator::GenerateInitializationCode( + io::Printer* printer) const { + if (!IsDefaultValueJavaDefault(descriptor_)) { + printer->Print(variables_, "$name$_ = $default$;\n"); + } +} + +void ImmutablePrimitiveFieldGenerator::GenerateBuilderClearCode( + io::Printer* printer) const { + printer->Print(variables_, + "$name$_ = $default$;\n" + "$clear_has_field_bit_builder$\n"); +} + +void ImmutablePrimitiveFieldGenerator::GenerateMergingCode( + io::Printer* printer) const { + if (HasHazzer(descriptor_)) { + printer->Print(variables_, + "if (other.has$capitalized_name$()) {\n" + " set$capitalized_name$(other.get$capitalized_name$());\n" + "}\n"); + } else { + printer->Print(variables_, + "if (other.get$capitalized_name$() != $default$) {\n" + " set$capitalized_name$(other.get$capitalized_name$());\n" + "}\n"); + } +} + +void ImmutablePrimitiveFieldGenerator::GenerateBuildingCode( + io::Printer* printer) const { + if (HasHazzer(descriptor_)) { + if (IsDefaultValueJavaDefault(descriptor_)) { + printer->Print(variables_, + "if ($get_has_field_bit_from_local$) {\n" + " result.$name$_ = $name$_;\n" + " $set_has_field_bit_to_local$;\n" + "}\n"); + } else { + printer->Print(variables_, + "if ($get_has_field_bit_from_local$) {\n" + " $set_has_field_bit_to_local$;\n" + "}\n" + "result.$name$_ = $name$_;\n"); + } + } else { + printer->Print(variables_, "result.$name$_ = $name$_;\n"); + } +} + +void ImmutablePrimitiveFieldGenerator::GenerateParsingCode( + io::Printer* printer) const { + printer->Print(variables_, + "$set_has_field_bit_message$\n" + "$name$_ = input.read$capitalized_type$();\n"); +} + +void ImmutablePrimitiveFieldGenerator::GenerateParsingDoneCode( + io::Printer* printer) const { + // noop for primitives. +} + +void ImmutablePrimitiveFieldGenerator::GenerateSerializationCode( + io::Printer* printer) const { + printer->Print(variables_, + "if ($is_field_present_message$) {\n" + " output.write$capitalized_type$($number$, $name$_);\n" + "}\n"); +} + +void ImmutablePrimitiveFieldGenerator::GenerateSerializedSizeCode( + io::Printer* printer) const { + printer->Print(variables_, + "if ($is_field_present_message$) {\n" + " size += com.google.protobuf.CodedOutputStream\n" + " .compute$capitalized_type$Size($number$, $name$_);\n" + "}\n"); +} + +void ImmutablePrimitiveFieldGenerator::GenerateEqualsCode( + io::Printer* printer) const { + switch (GetJavaType(descriptor_)) { + case JAVATYPE_INT: + case JAVATYPE_LONG: + case JAVATYPE_BOOLEAN: + printer->Print(variables_, + "if (get$capitalized_name$()\n" + " != other.get$capitalized_name$()) return false;\n"); + break; + + case JAVATYPE_FLOAT: + printer->Print( + variables_, + "if (java.lang.Float.floatToIntBits(get$capitalized_name$())\n" + " != java.lang.Float.floatToIntBits(\n" + " other.get$capitalized_name$())) return false;\n"); + break; + + case JAVATYPE_DOUBLE: + printer->Print( + variables_, + "if (java.lang.Double.doubleToLongBits(get$capitalized_name$())\n" + " != java.lang.Double.doubleToLongBits(\n" + " other.get$capitalized_name$())) return false;\n"); + break; + + case JAVATYPE_STRING: + case JAVATYPE_BYTES: + printer->Print( + variables_, + "if (!get$capitalized_name$()\n" + " .equals(other.get$capitalized_name$())) return false;\n"); + break; + + case JAVATYPE_ENUM: + case JAVATYPE_MESSAGE: + default: + GOOGLE_LOG(FATAL) << "Can't get here."; + break; + } +} + +void ImmutablePrimitiveFieldGenerator::GenerateHashCode( + io::Printer* printer) const { + printer->Print(variables_, "hash = (37 * hash) + $constant_name$;\n"); + switch (GetJavaType(descriptor_)) { + case JAVATYPE_INT: + printer->Print(variables_, + "hash = (53 * hash) + get$capitalized_name$();\n"); + break; + + case JAVATYPE_LONG: + printer->Print( + variables_, + "hash = (53 * hash) + com.google.protobuf.Internal.hashLong(\n" + " get$capitalized_name$());\n"); + break; + + case JAVATYPE_BOOLEAN: + printer->Print( + variables_, + "hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(\n" + " get$capitalized_name$());\n"); + break; + + case JAVATYPE_FLOAT: + printer->Print(variables_, + "hash = (53 * hash) + java.lang.Float.floatToIntBits(\n" + " get$capitalized_name$());\n"); + break; + + case JAVATYPE_DOUBLE: + printer->Print( + variables_, + "hash = (53 * hash) + com.google.protobuf.Internal.hashLong(\n" + " java.lang.Double.doubleToLongBits(get$capitalized_name$()));\n"); + break; + + case JAVATYPE_STRING: + case JAVATYPE_BYTES: + printer->Print( + variables_, + "hash = (53 * hash) + get$capitalized_name$().hashCode();\n"); + break; + + case JAVATYPE_ENUM: + case JAVATYPE_MESSAGE: + default: + GOOGLE_LOG(FATAL) << "Can't get here."; + break; + } +} + +std::string ImmutablePrimitiveFieldGenerator::GetBoxedType() const { + return BoxedPrimitiveTypeName(GetJavaType(descriptor_)); +} + +// =================================================================== + +ImmutablePrimitiveOneofFieldGenerator::ImmutablePrimitiveOneofFieldGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, + Context* context) + : ImmutablePrimitiveFieldGenerator(descriptor, messageBitIndex, + builderBitIndex, context) { + const OneofGeneratorInfo* info = + context->GetOneofGeneratorInfo(descriptor->containing_oneof()); + SetCommonOneofVariables(descriptor, info, &variables_); +} + +ImmutablePrimitiveOneofFieldGenerator:: + ~ImmutablePrimitiveOneofFieldGenerator() {} + +void ImmutablePrimitiveOneofFieldGenerator::GenerateMembers( + io::Printer* printer) const { + PrintExtraFieldInfo(variables_, printer); + GOOGLE_DCHECK(HasHazzer(descriptor_)); + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return $has_oneof_case_message$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" + " if ($has_oneof_case_message$) {\n" + " return ($boxed_type$) $oneof_name$_;\n" + " }\n" + " return $default$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +void ImmutablePrimitiveOneofFieldGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + GOOGLE_DCHECK(HasHazzer(descriptor_)); + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print(variables_, + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return $has_oneof_case_message$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" + " if ($has_oneof_case_message$) {\n" + " return ($boxed_type$) $oneof_name$_;\n" + " }\n" + " return $default$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldAccessorDocComment(printer, descriptor_, SETTER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder " + "${$set$capitalized_name$$}$($type$ value) {\n" + "$null_check$" + " $set_oneof_case_message$;\n" + " $oneof_name$_ = value;\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ true); + printer->Print( + variables_, + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" + " if ($has_oneof_case_message$) {\n" + " $clear_oneof_case_message$;\n" + " $oneof_name$_ = null;\n" + " $on_changed$\n" + " }\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +void ImmutablePrimitiveOneofFieldGenerator::GenerateBuildingCode( + io::Printer* printer) const { + printer->Print(variables_, + "if ($has_oneof_case_message$) {\n" + " result.$oneof_name$_ = $oneof_name$_;\n" + "}\n"); +} + +void ImmutablePrimitiveOneofFieldGenerator::GenerateMergingCode( + io::Printer* printer) const { + printer->Print(variables_, + "set$capitalized_name$(other.get$capitalized_name$());\n"); +} + +void ImmutablePrimitiveOneofFieldGenerator::GenerateParsingCode( + io::Printer* printer) const { + printer->Print(variables_, + "$oneof_name$_ = input.read$capitalized_type$();\n" + "$set_oneof_case_message$;\n"); +} + +void ImmutablePrimitiveOneofFieldGenerator::GenerateSerializationCode( + io::Printer* printer) const { + printer->Print(variables_, + "if ($has_oneof_case_message$) {\n" + " output.write$capitalized_type$(\n"); + // $type$ and $boxed_type$ is the same for bytes fields so we don't need to + // do redundant casts. + if (GetJavaType(descriptor_) == JAVATYPE_BYTES) { + printer->Print(variables_, " $number$, ($type$) $oneof_name$_);\n"); + } else { + printer->Print( + variables_, + " $number$, ($type$)(($boxed_type$) $oneof_name$_));\n"); + } + printer->Print("}\n"); +} + +void ImmutablePrimitiveOneofFieldGenerator::GenerateSerializedSizeCode( + io::Printer* printer) const { + printer->Print(variables_, + "if ($has_oneof_case_message$) {\n" + " size += com.google.protobuf.CodedOutputStream\n" + " .compute$capitalized_type$Size(\n"); + // $type$ and $boxed_type$ is the same for bytes fields so we don't need to + // do redundant casts. + if (GetJavaType(descriptor_) == JAVATYPE_BYTES) { + printer->Print(variables_, " $number$, ($type$) $oneof_name$_);\n"); + } else { + printer->Print( + variables_, + " $number$, ($type$)(($boxed_type$) $oneof_name$_));\n"); + } + printer->Print("}\n"); +} + +// =================================================================== + +RepeatedImmutablePrimitiveFieldGenerator:: + RepeatedImmutablePrimitiveFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex, + Context* context) + : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) { + SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex, + context->GetFieldGeneratorInfo(descriptor), + name_resolver_, &variables_); +} + +RepeatedImmutablePrimitiveFieldGenerator:: + ~RepeatedImmutablePrimitiveFieldGenerator() {} + +int RepeatedImmutablePrimitiveFieldGenerator::GetNumBitsForMessage() const { + return 0; +} + +int RepeatedImmutablePrimitiveFieldGenerator::GetNumBitsForBuilder() const { + return 1; +} + +void RepeatedImmutablePrimitiveFieldGenerator::GenerateInterfaceMembers( + io::Printer* printer) const { + WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER); + printer->Print(variables_, + "$deprecation$java.util.List<$boxed_type$> " + "get$capitalized_name$List();\n"); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT); + printer->Print(variables_, + "$deprecation$int get$capitalized_name$Count();\n"); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER); + printer->Print(variables_, + "$deprecation$$type$ get$capitalized_name$(int index);\n"); +} + +void RepeatedImmutablePrimitiveFieldGenerator::GenerateMembers( + io::Printer* printer) const { + printer->Print(variables_, "private $field_list_type$ $name$_;\n"); + PrintExtraFieldInfo(variables_, printer); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public java.util.List<$boxed_type$>\n" + " ${$get$capitalized_name$List$}$() {\n" + " return $name$_;\n" // note: unmodifiable list + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT); + printer->Print( + variables_, + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" + " return $name$_.size();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER); + printer->Print( + variables_, + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" + " return $repeated_get$(index);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + if (descriptor_->is_packed()) { + printer->Print(variables_, + "private int $name$MemoizedSerializedSize = -1;\n"); + } +} + +void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + // One field is the list and the bit field keeps track of whether the + // list is immutable. If it's immutable, the invariant is that it must + // either an instance of Collections.emptyList() or it's an ArrayList + // wrapped in a Collections.unmodifiableList() wrapper and nobody else has + // a reference to the underlying ArrayList. This invariant allows us to + // share instances of lists between protocol buffers avoiding expensive + // memory allocations. Note, immutable is a strong guarantee here -- not + // just that the list cannot be modified via the reference but that the + // list can never be modified. + printer->Print(variables_, + "private $field_list_type$ $name$_ = $empty_list$;\n"); + + printer->Print(variables_, + "private void ensure$capitalized_name$IsMutable() {\n" + " if (!$get_mutable_bit_builder$) {\n" + " $name$_ = $mutable_copy_list$;\n" + " $set_mutable_bit_builder$;\n" + " }\n" + "}\n"); + + // Note: We return an unmodifiable list because otherwise the caller + // could hold on to the returned list and modify it after the message + // has been built, thus mutating the message which is supposed to be + // immutable. + WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER); + printer->Print( + variables_, + "$deprecation$public java.util.List<$boxed_type$>\n" + " ${$get$capitalized_name$List$}$() {\n" + " return $get_mutable_bit_builder$ ?\n" + " java.util.Collections.unmodifiableList($name$_) : $name$_;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT); + printer->Print( + variables_, + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" + " return $name$_.size();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER); + printer->Print( + variables_, + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" + " return $repeated_get$(index);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" + " int index, $type$ value) {\n" + "$null_check$" + " ensure$capitalized_name$IsMutable();\n" + " $repeated_set$(index, value);\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder " + "${$add$capitalized_name$$}$($type$ value) {\n" + "$null_check$" + " ensure$capitalized_name$IsMutable();\n" + " $repeated_add$(value);\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n" + " java.lang.Iterable<? extends $boxed_type$> values) {\n" + " ensure$capitalized_name$IsMutable();\n" + " com.google.protobuf.AbstractMessageLite.Builder.addAll(\n" + " values, $name$_);\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ true); + printer->Print( + variables_, + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" + " $name$_ = $empty_list$;\n" + " $clear_mutable_bit_builder$;\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +void RepeatedImmutablePrimitiveFieldGenerator::GenerateKotlinDslMembers( + io::Printer* printer) const { + printer->Print( + variables_, + "/**\n" + " * An uninstantiable, behaviorless type to represent the field in\n" + " * generics.\n" + " */\n" + "@kotlin.OptIn" + "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n" + "public class ${$$kt_capitalized_name$Proxy$}$ private constructor()" + " : com.google.protobuf.kotlin.DslProxy()\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$kt_deprecation$ public val $kt_name$: " + "com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>\n" + " @kotlin.jvm.JvmSynthetic\n" + " get() = com.google.protobuf.kotlin.DslList(\n" + " $kt_dsl_builder$.${$get$capitalized_name$List$}$()\n" + " )\n"); + + WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, + /* builder */ false); + printer->Print(variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"add$kt_capitalized_name$\")\n" + "public fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "add(value: $kt_type$) {\n" + " $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n" + "}"); + + WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, + /* builder */ false); + printer->Print(variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"plusAssign$kt_capitalized_name$\")\n" + "@Suppress(\"NOTHING_TO_INLINE\")\n" + "public inline operator fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "plusAssign(value: $kt_type$) {\n" + " add(value)\n" + "}"); + + WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, + /* builder */ false); + printer->Print(variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"addAll$kt_capitalized_name$\")\n" + "public fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "addAll(values: kotlin.collections.Iterable<$kt_type$>) {\n" + " $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n" + "}"); + + WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, + /* builder */ false); + printer->Print( + variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"plusAssignAll$kt_capitalized_name$\")\n" + "@Suppress(\"NOTHING_TO_INLINE\")\n" + "public inline operator fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "plusAssign(values: kotlin.collections.Iterable<$kt_type$>) {\n" + " addAll(values)\n" + "}"); + + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER, + /* builder */ false); + printer->Print( + variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"set$kt_capitalized_name$\")\n" + "public operator fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "set(index: kotlin.Int, value: $kt_type$) {\n" + " $kt_dsl_builder$.${$set$capitalized_name$$}$(index, value)\n" + "}"); + + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ false); + printer->Print(variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"clear$kt_capitalized_name$\")\n" + "public fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "clear() {\n" + " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n" + "}"); +} + +void RepeatedImmutablePrimitiveFieldGenerator:: + GenerateFieldBuilderInitializationCode(io::Printer* printer) const { + // noop for primitives +} + +void RepeatedImmutablePrimitiveFieldGenerator::GenerateInitializationCode( + io::Printer* printer) const { + printer->Print(variables_, "$name$_ = $empty_list$;\n"); +} + +void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderClearCode( + io::Printer* printer) const { + printer->Print(variables_, + "$name$_ = $empty_list$;\n" + "$clear_mutable_bit_builder$;\n"); +} + +void RepeatedImmutablePrimitiveFieldGenerator::GenerateMergingCode( + io::Printer* printer) const { + // The code below does two optimizations: + // 1. If the other list is empty, there's nothing to do. This ensures we + // don't allocate a new array if we already have an immutable one. + // 2. If the other list is non-empty and our current list is empty, we can + // reuse the other list which is guaranteed to be immutable. + printer->Print(variables_, + "if (!other.$name$_.isEmpty()) {\n" + " if ($name$_.isEmpty()) {\n" + " $name$_ = other.$name$_;\n" + " $clear_mutable_bit_builder$;\n" + " } else {\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.addAll(other.$name$_);\n" + " }\n" + " $on_changed$\n" + "}\n"); +} + +void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuildingCode( + io::Printer* printer) const { + // The code below ensures that the result has an immutable list. If our + // list is immutable, we can just reuse it. If not, we make it immutable. + printer->Print(variables_, + "if ($get_mutable_bit_builder$) {\n" + " $name_make_immutable$;\n" + " $clear_mutable_bit_builder$;\n" + "}\n" + "result.$name$_ = $name$_;\n"); +} + +void RepeatedImmutablePrimitiveFieldGenerator::GenerateParsingCode( + io::Printer* printer) const { + printer->Print(variables_, + "if (!$get_mutable_bit_parser$) {\n" + " $name$_ = $create_list$;\n" + " $set_mutable_bit_parser$;\n" + "}\n" + "$repeated_add$(input.read$capitalized_type$());\n"); +} + +void RepeatedImmutablePrimitiveFieldGenerator::GenerateParsingCodeFromPacked( + io::Printer* printer) const { + printer->Print( + variables_, + "int length = input.readRawVarint32();\n" + "int limit = input.pushLimit(length);\n" + "if (!$get_mutable_bit_parser$ && input.getBytesUntilLimit() > 0) {\n" + " $name$_ = $create_list$;\n" + " $set_mutable_bit_parser$;\n" + "}\n" + "while (input.getBytesUntilLimit() > 0) {\n" + " $repeated_add$(input.read$capitalized_type$());\n" + "}\n" + "input.popLimit(limit);\n"); +} + +void RepeatedImmutablePrimitiveFieldGenerator::GenerateParsingDoneCode( + io::Printer* printer) const { + printer->Print(variables_, + "if ($get_mutable_bit_parser$) {\n" + " $name_make_immutable$; // C\n" + "}\n"); +} + +void RepeatedImmutablePrimitiveFieldGenerator::GenerateSerializationCode( + io::Printer* printer) const { + if (descriptor_->is_packed()) { + // We invoke getSerializedSize in writeTo for messages that have packed + // fields in ImmutableMessageGenerator::GenerateMessageSerializationMethods. + // That makes it safe to rely on the memoized size here. + printer->Print(variables_, + "if (get$capitalized_name$List().size() > 0) {\n" + " output.writeUInt32NoTag($tag$);\n" + " output.writeUInt32NoTag($name$MemoizedSerializedSize);\n" + "}\n" + "for (int i = 0; i < $name$_.size(); i++) {\n" + " output.write$capitalized_type$NoTag($repeated_get$(i));\n" + "}\n"); + } else { + printer->Print( + variables_, + "for (int i = 0; i < $name$_.size(); i++) {\n" + " output.write$capitalized_type$($number$, $repeated_get$(i));\n" + "}\n"); + } +} + +void RepeatedImmutablePrimitiveFieldGenerator::GenerateSerializedSizeCode( + io::Printer* printer) const { + printer->Print(variables_, + "{\n" + " int dataSize = 0;\n"); + printer->Indent(); + + if (FixedSize(GetType(descriptor_)) == -1) { + printer->Print( + variables_, + "for (int i = 0; i < $name$_.size(); i++) {\n" + " dataSize += com.google.protobuf.CodedOutputStream\n" + " .compute$capitalized_type$SizeNoTag($repeated_get$(i));\n" + "}\n"); + } else { + printer->Print( + variables_, + "dataSize = $fixed_size$ * get$capitalized_name$List().size();\n"); + } + + printer->Print("size += dataSize;\n"); + + if (descriptor_->is_packed()) { + printer->Print(variables_, + "if (!get$capitalized_name$List().isEmpty()) {\n" + " size += $tag_size$;\n" + " size += com.google.protobuf.CodedOutputStream\n" + " .computeInt32SizeNoTag(dataSize);\n" + "}\n"); + } else { + printer->Print( + variables_, + "size += $tag_size$ * get$capitalized_name$List().size();\n"); + } + + // cache the data size for packed fields. + if (descriptor_->is_packed()) { + printer->Print(variables_, "$name$MemoizedSerializedSize = dataSize;\n"); + } + + printer->Outdent(); + printer->Print("}\n"); +} + +void RepeatedImmutablePrimitiveFieldGenerator::GenerateEqualsCode( + io::Printer* printer) const { + printer->Print( + variables_, + "if (!get$capitalized_name$List()\n" + " .equals(other.get$capitalized_name$List())) return false;\n"); +} + +void RepeatedImmutablePrimitiveFieldGenerator::GenerateHashCode( + io::Printer* printer) const { + printer->Print( + variables_, + "if (get$capitalized_name$Count() > 0) {\n" + " hash = (37 * hash) + $constant_name$;\n" + " hash = (53 * hash) + get$capitalized_name$List().hashCode();\n" + "}\n"); +} + +std::string RepeatedImmutablePrimitiveFieldGenerator::GetBoxedType() const { + return BoxedPrimitiveTypeName(GetJavaType(descriptor_)); +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_primitive_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_primitive_field.h new file mode 100644 index 00000000..2291ecb2 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_primitive_field.h @@ -0,0 +1,162 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_PRIMITIVE_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_PRIMITIVE_FIELD_H__ + +#include <map> +#include <string> +#include <compiler/java/java_field.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { +class Context; // context.h +class ClassNameResolver; // name_resolver.h +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +class ImmutablePrimitiveFieldGenerator : public ImmutableFieldGenerator { + public: + explicit ImmutablePrimitiveFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex, + Context* context); + ~ImmutablePrimitiveFieldGenerator() override; + + // implements ImmutableFieldGenerator + // --------------------------------------- + int GetNumBitsForMessage() const override; + int GetNumBitsForBuilder() const override; + void GenerateInterfaceMembers(io::Printer* printer) const override; + void GenerateMembers(io::Printer* printer) const override; + void GenerateBuilderMembers(io::Printer* printer) const override; + void GenerateInitializationCode(io::Printer* printer) const override; + void GenerateBuilderClearCode(io::Printer* printer) const override; + void GenerateMergingCode(io::Printer* printer) const override; + void GenerateBuildingCode(io::Printer* printer) const override; + void GenerateParsingCode(io::Printer* printer) const override; + void GenerateParsingDoneCode(io::Printer* printer) const override; + void GenerateSerializationCode(io::Printer* printer) const override; + void GenerateSerializedSizeCode(io::Printer* printer) const override; + void GenerateFieldBuilderInitializationCode( + io::Printer* printer) const override; + void GenerateEqualsCode(io::Printer* printer) const override; + void GenerateHashCode(io::Printer* printer) const override; + void GenerateKotlinDslMembers(io::Printer* printer) const override; + + std::string GetBoxedType() const override; + + protected: + const FieldDescriptor* descriptor_; + std::map<std::string, std::string> variables_; + ClassNameResolver* name_resolver_; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutablePrimitiveFieldGenerator); +}; + +class ImmutablePrimitiveOneofFieldGenerator + : public ImmutablePrimitiveFieldGenerator { + public: + ImmutablePrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex, Context* context); + ~ImmutablePrimitiveOneofFieldGenerator(); + + void GenerateMembers(io::Printer* printer) const override; + void GenerateBuilderMembers(io::Printer* printer) const override; + void GenerateBuildingCode(io::Printer* printer) const override; + void GenerateMergingCode(io::Printer* printer) const override; + void GenerateParsingCode(io::Printer* printer) const override; + void GenerateSerializationCode(io::Printer* printer) const override; + void GenerateSerializedSizeCode(io::Printer* printer) const override; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutablePrimitiveOneofFieldGenerator); +}; + +class RepeatedImmutablePrimitiveFieldGenerator + : public ImmutableFieldGenerator { + public: + explicit RepeatedImmutablePrimitiveFieldGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, + int builderBitIndex, Context* context); + ~RepeatedImmutablePrimitiveFieldGenerator() override; + + // implements ImmutableFieldGenerator --------------------------------------- + int GetNumBitsForMessage() const override; + int GetNumBitsForBuilder() const override; + void GenerateInterfaceMembers(io::Printer* printer) const override; + void GenerateMembers(io::Printer* printer) const override; + void GenerateBuilderMembers(io::Printer* printer) const override; + void GenerateInitializationCode(io::Printer* printer) const override; + void GenerateBuilderClearCode(io::Printer* printer) const override; + void GenerateMergingCode(io::Printer* printer) const override; + void GenerateBuildingCode(io::Printer* printer) const override; + void GenerateParsingCode(io::Printer* printer) const override; + void GenerateParsingCodeFromPacked(io::Printer* printer) const override; + void GenerateParsingDoneCode(io::Printer* printer) const override; + void GenerateSerializationCode(io::Printer* printer) const override; + void GenerateSerializedSizeCode(io::Printer* printer) const override; + void GenerateFieldBuilderInitializationCode( + io::Printer* printer) const override; + void GenerateEqualsCode(io::Printer* printer) const override; + void GenerateHashCode(io::Printer* printer) const override; + void GenerateKotlinDslMembers(io::Printer* printer) const override; + + std::string GetBoxedType() const override; + + private: + const FieldDescriptor* descriptor_; + std::map<std::string, std::string> variables_; + ClassNameResolver* name_resolver_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutablePrimitiveFieldGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_PRIMITIVE_FIELD_H__ diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_primitive_field_lite.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_primitive_field_lite.cc new file mode 100644 index 00000000..7b680a70 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_primitive_field_lite.cc @@ -0,0 +1,779 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <compiler/java/java_primitive_field_lite.h> + +#include <cstdint> +#include <map> +#include <string> + +#include <stubs/logging.h> +#include <stubs/common.h> +#include <compiler/java/java_context.h> +#include <compiler/java/java_doc_comment.h> +#include <compiler/java/java_helpers.h> +#include <compiler/java/java_name_resolver.h> +#include <io/printer.h> +#include <wire_format.h> +#include <stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +using internal::WireFormat; +using internal::WireFormatLite; + +namespace { +bool EnableExperimentalRuntimeForLite() { +#ifdef PROTOBUF_EXPERIMENT + return PROTOBUF_EXPERIMENT; +#else // PROTOBUF_EXPERIMENT + return false; +#endif // !PROTOBUF_EXPERIMENT +} + +void SetPrimitiveVariables(const FieldDescriptor* descriptor, + int messageBitIndex, int builderBitIndex, + const FieldGeneratorInfo* info, + ClassNameResolver* name_resolver, + std::map<std::string, std::string>* variables) { + SetCommonFieldVariables(descriptor, info, variables); + JavaType javaType = GetJavaType(descriptor); + (*variables)["type"] = PrimitiveTypeName(javaType); + (*variables)["boxed_type"] = BoxedPrimitiveTypeName(javaType); + (*variables)["kt_type"] = KotlinTypeName(javaType); + (*variables)["field_type"] = (*variables)["type"]; + (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver); + (*variables)["capitalized_type"] = + GetCapitalizedType(descriptor, /* immutable = */ true); + (*variables)["tag"] = + StrCat(static_cast<int32_t>(WireFormat::MakeTag(descriptor))); + (*variables)["tag_size"] = StrCat( + WireFormat::TagSize(descriptor->number(), GetType(descriptor))); + (*variables)["required"] = descriptor->is_required() ? "true" : "false"; + + std::string capitalized_type = UnderscoresToCamelCase( + PrimitiveTypeName(javaType), true /* cap_next_letter */); + switch (javaType) { + case JAVATYPE_INT: + case JAVATYPE_LONG: + case JAVATYPE_FLOAT: + case JAVATYPE_DOUBLE: + case JAVATYPE_BOOLEAN: + (*variables)["field_list_type"] = + "com.google.protobuf.Internal." + capitalized_type + "List"; + (*variables)["empty_list"] = "empty" + capitalized_type + "List()"; + (*variables)["make_name_unmodifiable"] = + (*variables)["name"] + "_.makeImmutable()"; + (*variables)["repeated_get"] = + (*variables)["name"] + "_.get" + capitalized_type; + (*variables)["repeated_add"] = + (*variables)["name"] + "_.add" + capitalized_type; + (*variables)["repeated_set"] = + (*variables)["name"] + "_.set" + capitalized_type; + (*variables)["visit_type"] = capitalized_type; + (*variables)["visit_type_list"] = "visit" + capitalized_type + "List"; + break; + default: + (*variables)["field_list_type"] = + "com.google.protobuf.Internal.ProtobufList<" + + (*variables)["boxed_type"] + ">"; + (*variables)["empty_list"] = "emptyProtobufList()"; + (*variables)["make_name_unmodifiable"] = + (*variables)["name"] + "_.makeImmutable()"; + (*variables)["repeated_get"] = (*variables)["name"] + "_.get"; + (*variables)["repeated_add"] = (*variables)["name"] + "_.add"; + (*variables)["repeated_set"] = (*variables)["name"] + "_.set"; + (*variables)["visit_type"] = "ByteString"; + (*variables)["visit_type_list"] = "visitList"; + } + + if (javaType == JAVATYPE_BYTES) { + (*variables)["bytes_default"] = + ToUpper((*variables)["name"]) + "_DEFAULT_VALUE"; + } + + if (IsReferenceType(javaType)) { + // We use `x.getClass()` as a null check because it generates less bytecode + // than an `if (x == null) { throw ... }` statement. + (*variables)["null_check"] = + " java.lang.Class<?> valueClass = value.getClass();\n"; + } else { + (*variables)["null_check"] = ""; + } + // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported + // by the proto compiler + (*variables)["deprecation"] = + descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; + (*variables)["kt_deprecation"] = + descriptor->options().deprecated() + ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] + + " is deprecated\") " + : ""; + int fixed_size = FixedSize(GetType(descriptor)); + if (fixed_size != -1) { + (*variables)["fixed_size"] = StrCat(fixed_size); + } + + if (HasHasbit(descriptor)) { + // For singular messages and builders, one bit is used for the hasField bit. + (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); + + // Note that these have a trailing ";". + (*variables)["set_has_field_bit_message"] = + GenerateSetBit(messageBitIndex) + ";"; + (*variables)["clear_has_field_bit_message"] = + GenerateClearBit(messageBitIndex) + ";"; + + (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex); + } else { + (*variables)["set_has_field_bit_message"] = ""; + (*variables)["set_has_field_bit_message"] = ""; + (*variables)["clear_has_field_bit_message"] = ""; + + switch (descriptor->type()) { + case FieldDescriptor::TYPE_BYTES: + (*variables)["is_field_present_message"] = + "!" + (*variables)["name"] + "_.isEmpty()"; + break; + case FieldDescriptor::TYPE_FLOAT: + (*variables)["is_field_present_message"] = + "java.lang.Float.floatToRawIntBits(" + (*variables)["name"] + + "_) != 0"; + break; + case FieldDescriptor::TYPE_DOUBLE: + (*variables)["is_field_present_message"] = + "java.lang.Double.doubleToRawLongBits(" + (*variables)["name"] + + "_) != 0"; + break; + default: + (*variables)["is_field_present_message"] = + (*variables)["name"] + "_ != " + (*variables)["default"]; + break; + } + } + + (*variables)["get_has_field_bit_from_local"] = + GenerateGetBitFromLocal(builderBitIndex); + (*variables)["set_has_field_bit_to_local"] = + GenerateSetBitToLocal(messageBitIndex); +} + +} // namespace + +// =================================================================== + +ImmutablePrimitiveFieldLiteGenerator::ImmutablePrimitiveFieldLiteGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, Context* context) + : descriptor_(descriptor), + messageBitIndex_(messageBitIndex), + name_resolver_(context->GetNameResolver()) { + SetPrimitiveVariables(descriptor, messageBitIndex, 0, + context->GetFieldGeneratorInfo(descriptor), + name_resolver_, &variables_); +} + +ImmutablePrimitiveFieldLiteGenerator::~ImmutablePrimitiveFieldLiteGenerator() {} + +int ImmutablePrimitiveFieldLiteGenerator::GetNumBitsForMessage() const { + return HasHasbit(descriptor_) ? 1 : 0; +} + +void ImmutablePrimitiveFieldLiteGenerator::GenerateInterfaceMembers( + io::Printer* printer) const { + if (HasHazzer(descriptor_)) { + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print(variables_, + "$deprecation$boolean has$capitalized_name$();\n"); + } + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n"); +} + +void ImmutablePrimitiveFieldLiteGenerator::GenerateMembers( + io::Printer* printer) const { + if (IsByteStringWithCustomDefaultValue(descriptor_)) { + // allocate this once statically since we know ByteStrings are immutable + // values that can be reused. + printer->Print( + variables_, + "private static final $field_type$ $bytes_default$ = $default$;\n"); + } + printer->Print(variables_, "private $field_type$ $name$_;\n"); + PrintExtraFieldInfo(variables_, printer); + if (HasHazzer(descriptor_)) { + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return $get_has_field_bit_message$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } + + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" + " return $name$_;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldAccessorDocComment(printer, descriptor_, SETTER); + printer->Print(variables_, + "private void set$capitalized_name$($type$ value) {\n" + "$null_check$" + " $set_has_field_bit_message$\n" + " $name$_ = value;\n" + "}\n"); + + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER); + printer->Print(variables_, + "private void clear$capitalized_name$() {\n" + " $clear_has_field_bit_message$\n"); + JavaType type = GetJavaType(descriptor_); + if (type == JAVATYPE_STRING || type == JAVATYPE_BYTES) { + // The default value is not a simple literal so we want to avoid executing + // it multiple times. Instead, get the default out of the default instance. + printer->Print( + variables_, + " $name$_ = getDefaultInstance().get$capitalized_name$();\n"); + } else { + printer->Print(variables_, " $name$_ = $default$;\n"); + } + printer->Print(variables_, "}\n"); +} + +void ImmutablePrimitiveFieldLiteGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + if (HasHazzer(descriptor_)) { + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return instance.has$capitalized_name$();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } + + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" + " return instance.get$capitalized_name$();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldAccessorDocComment(printer, descriptor_, SETTER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder " + "${$set$capitalized_name$$}$($type$ value) {\n" + " copyOnWrite();\n" + " instance.set$capitalized_name$(value);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ true); + printer->Print( + variables_, + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" + " copyOnWrite();\n" + " instance.clear$capitalized_name$();\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +void ImmutablePrimitiveFieldLiteGenerator::GenerateKotlinDslMembers( + io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$kt_deprecation$public var $kt_name$: $kt_type$\n" + " @JvmName(\"${$get$kt_capitalized_name$$}$\")\n" + " get() = $kt_dsl_builder$.${$get$capitalized_name$$}$()\n" + " @JvmName(\"${$set$kt_capitalized_name$$}$\")\n" + " set(value) {\n" + " $kt_dsl_builder$.${$set$capitalized_name$$}$(value)\n" + " }\n"); + + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ false); + printer->Print(variables_, + "public fun ${$clear$kt_capitalized_name$$}$() {\n" + " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n" + "}\n"); + + if (HasHazzer(descriptor_)) { + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print( + variables_, + "public fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n" + " return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n" + "}\n"); + } +} + +void ImmutablePrimitiveFieldLiteGenerator::GenerateFieldInfo( + io::Printer* printer, std::vector<uint16_t>* output) const { + WriteIntToUtf16CharSequence(descriptor_->number(), output); + WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_), + output); + if (HasHasbit(descriptor_)) { + WriteIntToUtf16CharSequence(messageBitIndex_, output); + } + printer->Print(variables_, "\"$name$_\",\n"); +} + +void ImmutablePrimitiveFieldLiteGenerator::GenerateInitializationCode( + io::Printer* printer) const { + if (IsByteStringWithCustomDefaultValue(descriptor_)) { + printer->Print(variables_, "$name$_ = $bytes_default$;\n"); + } else if (!IsDefaultValueJavaDefault(descriptor_)) { + printer->Print(variables_, "$name$_ = $default$;\n"); + } +} + +std::string ImmutablePrimitiveFieldLiteGenerator::GetBoxedType() const { + return BoxedPrimitiveTypeName(GetJavaType(descriptor_)); +} + +// =================================================================== + +ImmutablePrimitiveOneofFieldLiteGenerator:: + ImmutablePrimitiveOneofFieldLiteGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + Context* context) + : ImmutablePrimitiveFieldLiteGenerator(descriptor, messageBitIndex, + context) { + const OneofGeneratorInfo* info = + context->GetOneofGeneratorInfo(descriptor->containing_oneof()); + SetCommonOneofVariables(descriptor, info, &variables_); +} + +ImmutablePrimitiveOneofFieldLiteGenerator:: + ~ImmutablePrimitiveOneofFieldLiteGenerator() {} + +void ImmutablePrimitiveOneofFieldLiteGenerator::GenerateMembers( + io::Printer* printer) const { + PrintExtraFieldInfo(variables_, printer); + GOOGLE_DCHECK(HasHazzer(descriptor_)); + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return $has_oneof_case_message$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" + " if ($has_oneof_case_message$) {\n" + " return ($boxed_type$) $oneof_name$_;\n" + " }\n" + " return $default$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldAccessorDocComment(printer, descriptor_, SETTER); + printer->Print(variables_, + "private void set$capitalized_name$($type$ value) {\n" + "$null_check$" + " $set_oneof_case_message$;\n" + " $oneof_name$_ = value;\n" + "}\n"); + + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER); + printer->Print(variables_, + "private void clear$capitalized_name$() {\n" + " if ($has_oneof_case_message$) {\n" + " $clear_oneof_case_message$;\n" + " $oneof_name$_ = null;\n" + " }\n" + "}\n"); +} + +void ImmutablePrimitiveOneofFieldLiteGenerator::GenerateFieldInfo( + io::Printer* printer, std::vector<uint16_t>* output) const { + WriteIntToUtf16CharSequence(descriptor_->number(), output); + WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_), + output); + WriteIntToUtf16CharSequence(descriptor_->containing_oneof()->index(), output); +} + +void ImmutablePrimitiveOneofFieldLiteGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + GOOGLE_DCHECK(HasHazzer(descriptor_)); + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return instance.has$capitalized_name$();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n" + " return instance.get$capitalized_name$();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldAccessorDocComment(printer, descriptor_, SETTER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder " + "${$set$capitalized_name$$}$($type$ value) {\n" + " copyOnWrite();\n" + " instance.set$capitalized_name$(value);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ true); + printer->Print( + variables_, + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" + " copyOnWrite();\n" + " instance.clear$capitalized_name$();\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +// =================================================================== + +RepeatedImmutablePrimitiveFieldLiteGenerator:: + RepeatedImmutablePrimitiveFieldLiteGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, + Context* context) + : descriptor_(descriptor), + context_(context), + name_resolver_(context->GetNameResolver()) { + SetPrimitiveVariables(descriptor, messageBitIndex, 0, + context->GetFieldGeneratorInfo(descriptor), + name_resolver_, &variables_); +} + +RepeatedImmutablePrimitiveFieldLiteGenerator:: + ~RepeatedImmutablePrimitiveFieldLiteGenerator() {} + +int RepeatedImmutablePrimitiveFieldLiteGenerator::GetNumBitsForMessage() const { + return 0; +} + +void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateInterfaceMembers( + io::Printer* printer) const { + WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER); + printer->Print(variables_, + "$deprecation$java.util.List<$boxed_type$> " + "get$capitalized_name$List();\n"); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT); + printer->Print(variables_, + "$deprecation$int get$capitalized_name$Count();\n"); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER); + printer->Print(variables_, + "$deprecation$$type$ get$capitalized_name$(int index);\n"); +} + +void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateMembers( + io::Printer* printer) const { + printer->Print(variables_, "private $field_list_type$ $name$_;\n"); + PrintExtraFieldInfo(variables_, printer); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public java.util.List<$boxed_type$>\n" + " ${$get$capitalized_name$List$}$() {\n" + " return $name$_;\n" // note: unmodifiable list + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" + " return $name$_.size();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" + " return $repeated_get$(index);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + if (!EnableExperimentalRuntimeForLite() && descriptor_->is_packed() && + context_->HasGeneratedMethods(descriptor_->containing_type())) { + printer->Print(variables_, + "private int $name$MemoizedSerializedSize = -1;\n"); + } + + printer->Print( + variables_, + "private void ensure$capitalized_name$IsMutable() {\n" + // Use a temporary to avoid a redundant iget-object. + " $field_list_type$ tmp = $name$_;\n" + " if (!tmp.isModifiable()) {\n" + " $name$_ =\n" + " com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);\n" + " }\n" + "}\n"); + + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER); + printer->Print(variables_, + "private void set$capitalized_name$(\n" + " int index, $type$ value) {\n" + "$null_check$" + " ensure$capitalized_name$IsMutable();\n" + " $repeated_set$(index, value);\n" + "}\n"); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER); + printer->Print(variables_, + "private void add$capitalized_name$($type$ value) {\n" + "$null_check$" + " ensure$capitalized_name$IsMutable();\n" + " $repeated_add$(value);\n" + "}\n"); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER); + printer->Print(variables_, + "private void addAll$capitalized_name$(\n" + " java.lang.Iterable<? extends $boxed_type$> values) {\n" + " ensure$capitalized_name$IsMutable();\n" + " com.google.protobuf.AbstractMessageLite.addAll(\n" + " values, $name$_);\n" + "}\n"); + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER); + printer->Print(variables_, + "private void clear$capitalized_name$() {\n" + " $name$_ = $empty_list$;\n" + "}\n"); +} + +void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public java.util.List<$boxed_type$>\n" + " ${$get$capitalized_name$List$}$() {\n" + " return java.util.Collections.unmodifiableList(\n" + " instance.get$capitalized_name$List());\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" + " return instance.get$capitalized_name$Count();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n" + " return instance.get$capitalized_name$(index);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, SETTER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" + " int index, $type$ value) {\n" + " copyOnWrite();\n" + " instance.set$capitalized_name$(index, value);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder " + "${$add$capitalized_name$$}$($type$ value) {\n" + " copyOnWrite();\n" + " instance.add$capitalized_name$(value);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n" + " java.lang.Iterable<? extends $boxed_type$> values) {\n" + " copyOnWrite();\n" + " instance.addAll$capitalized_name$(values);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ true); + printer->Print( + variables_, + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" + " copyOnWrite();\n" + " instance.clear$capitalized_name$();\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateKotlinDslMembers( + io::Printer* printer) const { + printer->Print( + variables_, + "/**\n" + " * An uninstantiable, behaviorless type to represent the field in\n" + " * generics.\n" + " */\n" + "@kotlin.OptIn" + "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n" + "public class ${$$kt_capitalized_name$Proxy$}$ private constructor()" + " : com.google.protobuf.kotlin.DslProxy()\n"); + + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$kt_deprecation$ public val $kt_name$: " + "com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>\n" + " @kotlin.jvm.JvmSynthetic\n" + " get() = com.google.protobuf.kotlin.DslList(\n" + " $kt_dsl_builder$.${$get$capitalized_name$List$}$()\n" + " )\n"); + + WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, + /* builder */ false); + printer->Print(variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"add$kt_capitalized_name$\")\n" + "public fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "add(value: $kt_type$) {\n" + " $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n" + "}"); + + WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, + /* builder */ false); + printer->Print(variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"plusAssign$kt_capitalized_name$\")\n" + "@Suppress(\"NOTHING_TO_INLINE\")\n" + "public inline operator fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "plusAssign(value: $kt_type$) {\n" + " add(value)\n" + "}"); + + WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, + /* builder */ false); + printer->Print(variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"addAll$kt_capitalized_name$\")\n" + "public fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "addAll(values: kotlin.collections.Iterable<$kt_type$>) {\n" + " $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n" + "}"); + + WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, + /* builder */ false); + printer->Print( + variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"plusAssignAll$kt_capitalized_name$\")\n" + "@Suppress(\"NOTHING_TO_INLINE\")\n" + "public inline operator fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "plusAssign(values: kotlin.collections.Iterable<$kt_type$>) {\n" + " addAll(values)\n" + "}"); + + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER, + /* builder */ false); + printer->Print( + variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"set$kt_capitalized_name$\")\n" + "public operator fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "set(index: kotlin.Int, value: $kt_type$) {\n" + " $kt_dsl_builder$.${$set$capitalized_name$$}$(index, value)\n" + "}"); + + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ false); + printer->Print(variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"clear$kt_capitalized_name$\")\n" + "public fun com.google.protobuf.kotlin.DslList" + "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>." + "clear() {\n" + " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n" + "}"); +} + +void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateFieldInfo( + io::Printer* printer, std::vector<uint16_t>* output) const { + WriteIntToUtf16CharSequence(descriptor_->number(), output); + WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_), + output); + printer->Print(variables_, "\"$name$_\",\n"); +} + +void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateInitializationCode( + io::Printer* printer) const { + printer->Print(variables_, "$name$_ = $empty_list$;\n"); +} + +std::string RepeatedImmutablePrimitiveFieldLiteGenerator::GetBoxedType() const { + return BoxedPrimitiveTypeName(GetJavaType(descriptor_)); +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_primitive_field_lite.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_primitive_field_lite.h new file mode 100644 index 00000000..8bfd7ae2 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_primitive_field_lite.h @@ -0,0 +1,141 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_PRIMITIVE_FIELD_LITE_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_PRIMITIVE_FIELD_LITE_H__ + +#include <cstdint> +#include <map> +#include <string> + +#include <compiler/java/java_field.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { +class Context; // context.h +class ClassNameResolver; // name_resolver.h +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +class ImmutablePrimitiveFieldLiteGenerator + : public ImmutableFieldLiteGenerator { + public: + explicit ImmutablePrimitiveFieldLiteGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, Context* context); + ~ImmutablePrimitiveFieldLiteGenerator() override; + + // implements ImmutableFieldLiteGenerator + // ------------------------------------ + int GetNumBitsForMessage() const override; + void GenerateInterfaceMembers(io::Printer* printer) const override; + void GenerateMembers(io::Printer* printer) const override; + void GenerateBuilderMembers(io::Printer* printer) const override; + void GenerateInitializationCode(io::Printer* printer) const override; + void GenerateFieldInfo(io::Printer* printer, + std::vector<uint16_t>* output) const override; + void GenerateKotlinDslMembers(io::Printer* printer) const override; + + std::string GetBoxedType() const override; + + protected: + const FieldDescriptor* descriptor_; + std::map<std::string, std::string> variables_; + const int messageBitIndex_; + ClassNameResolver* name_resolver_; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutablePrimitiveFieldLiteGenerator); +}; + +class ImmutablePrimitiveOneofFieldLiteGenerator + : public ImmutablePrimitiveFieldLiteGenerator { + public: + ImmutablePrimitiveOneofFieldLiteGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + Context* context); + ~ImmutablePrimitiveOneofFieldLiteGenerator(); + + void GenerateMembers(io::Printer* printer) const override; + void GenerateBuilderMembers(io::Printer* printer) const override; + + void GenerateFieldInfo(io::Printer* printer, + std::vector<uint16_t>* output) const override; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutablePrimitiveOneofFieldLiteGenerator); +}; + +class RepeatedImmutablePrimitiveFieldLiteGenerator + : public ImmutableFieldLiteGenerator { + public: + explicit RepeatedImmutablePrimitiveFieldLiteGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, Context* context); + ~RepeatedImmutablePrimitiveFieldLiteGenerator() override; + + // implements ImmutableFieldLiteGenerator ------------------------------------ + int GetNumBitsForMessage() const override; + void GenerateInterfaceMembers(io::Printer* printer) const override; + void GenerateMembers(io::Printer* printer) const override; + void GenerateBuilderMembers(io::Printer* printer) const override; + void GenerateInitializationCode(io::Printer* printer) const override; + void GenerateFieldInfo(io::Printer* printer, + std::vector<uint16_t>* output) const override; + void GenerateKotlinDslMembers(io::Printer* printer) const override; + + std::string GetBoxedType() const override; + + private: + const FieldDescriptor* descriptor_; + std::map<std::string, std::string> variables_; + Context* context_; + ClassNameResolver* name_resolver_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutablePrimitiveFieldLiteGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_PRIMITIVE_FIELD_LITE_H__ diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_service.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_service.cc new file mode 100644 index 00000000..28407660 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_service.cc @@ -0,0 +1,474 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <compiler/java/java_service.h> + +#include <compiler/java/java_context.h> +#include <compiler/java/java_doc_comment.h> +#include <compiler/java/java_helpers.h> +#include <compiler/java/java_name_resolver.h> +#include <io/printer.h> +#include <stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +ServiceGenerator::ServiceGenerator(const ServiceDescriptor* descriptor) + : descriptor_(descriptor) {} + +ServiceGenerator::~ServiceGenerator() {} + +// =================================================================== +ImmutableServiceGenerator::ImmutableServiceGenerator( + const ServiceDescriptor* descriptor, Context* context) + : ServiceGenerator(descriptor), + context_(context), + name_resolver_(context->GetNameResolver()) {} + +ImmutableServiceGenerator::~ImmutableServiceGenerator() {} + +void ImmutableServiceGenerator::Generate(io::Printer* printer) { + bool is_own_file = IsOwnFile(descriptor_, /* immutable = */ true); + WriteServiceDocComment(printer, descriptor_); + MaybePrintGeneratedAnnotation(context_, printer, descriptor_, + /* immutable = */ true); + printer->Print( + "public $static$ abstract class $classname$\n" + " implements com.google.protobuf.Service {\n", + "static", is_own_file ? "" : "static", "classname", descriptor_->name()); + printer->Indent(); + + printer->Print("protected $classname$() {}\n\n", "classname", + descriptor_->name()); + + GenerateInterface(printer); + + GenerateNewReflectiveServiceMethod(printer); + GenerateNewReflectiveBlockingServiceMethod(printer); + + GenerateAbstractMethods(printer); + + // Generate getDescriptor() and getDescriptorForType(). + printer->Print( + "public static final\n" + " com.google.protobuf.Descriptors.ServiceDescriptor\n" + " getDescriptor() {\n" + " return $file$.getDescriptor().getServices().get($index$);\n" + "}\n", + "file", name_resolver_->GetImmutableClassName(descriptor_->file()), + "index", StrCat(descriptor_->index())); + GenerateGetDescriptorForType(printer); + + // Generate more stuff. + GenerateCallMethod(printer); + GenerateGetPrototype(REQUEST, printer); + GenerateGetPrototype(RESPONSE, printer); + GenerateStub(printer); + GenerateBlockingStub(printer); + + // Add an insertion point. + printer->Print( + "\n" + "// @@protoc_insertion_point(class_scope:$full_name$)\n", + "full_name", descriptor_->full_name()); + + printer->Outdent(); + printer->Print("}\n\n"); +} + +void ImmutableServiceGenerator::GenerateGetDescriptorForType( + io::Printer* printer) { + printer->Print( + "public final com.google.protobuf.Descriptors.ServiceDescriptor\n" + " getDescriptorForType() {\n" + " return getDescriptor();\n" + "}\n"); +} + +void ImmutableServiceGenerator::GenerateInterface(io::Printer* printer) { + printer->Print("public interface Interface {\n"); + printer->Indent(); + GenerateAbstractMethods(printer); + printer->Outdent(); + printer->Print("}\n\n"); +} + +void ImmutableServiceGenerator::GenerateNewReflectiveServiceMethod( + io::Printer* printer) { + printer->Print( + "public static com.google.protobuf.Service newReflectiveService(\n" + " final Interface impl) {\n" + " return new $classname$() {\n", + "classname", descriptor_->name()); + printer->Indent(); + printer->Indent(); + + for (int i = 0; i < descriptor_->method_count(); i++) { + const MethodDescriptor* method = descriptor_->method(i); + printer->Print("@java.lang.Override\n"); + GenerateMethodSignature(printer, method, IS_CONCRETE); + printer->Print( + " {\n" + " impl.$method$(controller, request, done);\n" + "}\n\n", + "method", UnderscoresToCamelCase(method)); + } + + printer->Outdent(); + printer->Print("};\n"); + printer->Outdent(); + printer->Print("}\n\n"); +} + +void ImmutableServiceGenerator::GenerateNewReflectiveBlockingServiceMethod( + io::Printer* printer) { + printer->Print( + "public static com.google.protobuf.BlockingService\n" + " newReflectiveBlockingService(final BlockingInterface impl) {\n" + " return new com.google.protobuf.BlockingService() {\n"); + printer->Indent(); + printer->Indent(); + + GenerateGetDescriptorForType(printer); + + GenerateCallBlockingMethod(printer); + GenerateGetPrototype(REQUEST, printer); + GenerateGetPrototype(RESPONSE, printer); + + printer->Outdent(); + printer->Print("};\n"); + printer->Outdent(); + printer->Print("}\n\n"); +} + +void ImmutableServiceGenerator::GenerateAbstractMethods(io::Printer* printer) { + for (int i = 0; i < descriptor_->method_count(); i++) { + const MethodDescriptor* method = descriptor_->method(i); + WriteMethodDocComment(printer, method); + GenerateMethodSignature(printer, method, IS_ABSTRACT); + printer->Print(";\n\n"); + } +} + +std::string ImmutableServiceGenerator::GetOutput( + const MethodDescriptor* method) { + return name_resolver_->GetImmutableClassName(method->output_type()); +} + +void ImmutableServiceGenerator::GenerateCallMethod(io::Printer* printer) { + printer->Print( + "\n" + "public final void callMethod(\n" + " com.google.protobuf.Descriptors.MethodDescriptor method,\n" + " com.google.protobuf.RpcController controller,\n" + " com.google.protobuf.Message request,\n" + " com.google.protobuf.RpcCallback<\n" + " com.google.protobuf.Message> done) {\n" + " if (method.getService() != getDescriptor()) {\n" + " throw new java.lang.IllegalArgumentException(\n" + " \"Service.callMethod() given method descriptor for wrong \" +\n" + " \"service type.\");\n" + " }\n" + " switch(method.getIndex()) {\n"); + printer->Indent(); + printer->Indent(); + + for (int i = 0; i < descriptor_->method_count(); i++) { + const MethodDescriptor* method = descriptor_->method(i); + std::map<std::string, std::string> vars; + vars["index"] = StrCat(i); + vars["method"] = UnderscoresToCamelCase(method); + vars["input"] = name_resolver_->GetImmutableClassName(method->input_type()); + vars["output"] = GetOutput(method); + printer->Print( + vars, + "case $index$:\n" + " this.$method$(controller, ($input$)request,\n" + " com.google.protobuf.RpcUtil.<$output$>specializeCallback(\n" + " done));\n" + " return;\n"); + } + + printer->Print( + "default:\n" + " throw new java.lang.AssertionError(\"Can't get here.\");\n"); + + printer->Outdent(); + printer->Outdent(); + + printer->Print( + " }\n" + "}\n" + "\n"); +} + +void ImmutableServiceGenerator::GenerateCallBlockingMethod( + io::Printer* printer) { + printer->Print( + "\n" + "public final com.google.protobuf.Message callBlockingMethod(\n" + " com.google.protobuf.Descriptors.MethodDescriptor method,\n" + " com.google.protobuf.RpcController controller,\n" + " com.google.protobuf.Message request)\n" + " throws com.google.protobuf.ServiceException {\n" + " if (method.getService() != getDescriptor()) {\n" + " throw new java.lang.IllegalArgumentException(\n" + " \"Service.callBlockingMethod() given method descriptor for \" +\n" + " \"wrong service type.\");\n" + " }\n" + " switch(method.getIndex()) {\n"); + printer->Indent(); + printer->Indent(); + + for (int i = 0; i < descriptor_->method_count(); i++) { + const MethodDescriptor* method = descriptor_->method(i); + std::map<std::string, std::string> vars; + vars["index"] = StrCat(i); + vars["method"] = UnderscoresToCamelCase(method); + vars["input"] = name_resolver_->GetImmutableClassName(method->input_type()); + vars["output"] = GetOutput(method); + printer->Print(vars, + "case $index$:\n" + " return impl.$method$(controller, ($input$)request);\n"); + } + + printer->Print( + "default:\n" + " throw new java.lang.AssertionError(\"Can't get here.\");\n"); + + printer->Outdent(); + printer->Outdent(); + + printer->Print( + " }\n" + "}\n" + "\n"); +} + +void ImmutableServiceGenerator::GenerateGetPrototype(RequestOrResponse which, + io::Printer* printer) { + /* + * TODO(cpovirk): The exception message says "Service.foo" when it may be + * "BlockingService.foo." Consider fixing. + */ + printer->Print( + "public final com.google.protobuf.Message\n" + " get$request_or_response$Prototype(\n" + " com.google.protobuf.Descriptors.MethodDescriptor method) {\n" + " if (method.getService() != getDescriptor()) {\n" + " throw new java.lang.IllegalArgumentException(\n" + " \"Service.get$request_or_response$Prototype() given method \" +\n" + " \"descriptor for wrong service type.\");\n" + " }\n" + " switch(method.getIndex()) {\n", + "request_or_response", (which == REQUEST) ? "Request" : "Response"); + printer->Indent(); + printer->Indent(); + + for (int i = 0; i < descriptor_->method_count(); i++) { + const MethodDescriptor* method = descriptor_->method(i); + std::map<std::string, std::string> vars; + vars["index"] = StrCat(i); + vars["type"] = + (which == REQUEST) + ? name_resolver_->GetImmutableClassName(method->input_type()) + : GetOutput(method); + printer->Print(vars, + "case $index$:\n" + " return $type$.getDefaultInstance();\n"); + } + + printer->Print( + "default:\n" + " throw new java.lang.AssertionError(\"Can't get here.\");\n"); + + printer->Outdent(); + printer->Outdent(); + + printer->Print( + " }\n" + "}\n" + "\n"); +} + +void ImmutableServiceGenerator::GenerateStub(io::Printer* printer) { + printer->Print( + "public static Stub newStub(\n" + " com.google.protobuf.RpcChannel channel) {\n" + " return new Stub(channel);\n" + "}\n" + "\n" + "public static final class Stub extends $classname$ implements Interface " + "{" + "\n", + "classname", name_resolver_->GetImmutableClassName(descriptor_)); + printer->Indent(); + + printer->Print( + "private Stub(com.google.protobuf.RpcChannel channel) {\n" + " this.channel = channel;\n" + "}\n" + "\n" + "private final com.google.protobuf.RpcChannel channel;\n" + "\n" + "public com.google.protobuf.RpcChannel getChannel() {\n" + " return channel;\n" + "}\n"); + + for (int i = 0; i < descriptor_->method_count(); i++) { + const MethodDescriptor* method = descriptor_->method(i); + printer->Print("\n"); + GenerateMethodSignature(printer, method, IS_CONCRETE); + printer->Print(" {\n"); + printer->Indent(); + + std::map<std::string, std::string> vars; + vars["index"] = StrCat(i); + vars["output"] = GetOutput(method); + printer->Print(vars, + "channel.callMethod(\n" + " getDescriptor().getMethods().get($index$),\n" + " controller,\n" + " request,\n" + " $output$.getDefaultInstance(),\n" + " com.google.protobuf.RpcUtil.generalizeCallback(\n" + " done,\n" + " $output$.class,\n" + " $output$.getDefaultInstance()));\n"); + + printer->Outdent(); + printer->Print("}\n"); + } + + printer->Outdent(); + printer->Print( + "}\n" + "\n"); +} + +void ImmutableServiceGenerator::GenerateBlockingStub(io::Printer* printer) { + printer->Print( + "public static BlockingInterface newBlockingStub(\n" + " com.google.protobuf.BlockingRpcChannel channel) {\n" + " return new BlockingStub(channel);\n" + "}\n" + "\n"); + + printer->Print("public interface BlockingInterface {"); + printer->Indent(); + + for (int i = 0; i < descriptor_->method_count(); i++) { + const MethodDescriptor* method = descriptor_->method(i); + GenerateBlockingMethodSignature(printer, method); + printer->Print(";\n"); + } + + printer->Outdent(); + printer->Print( + "}\n" + "\n"); + + printer->Print( + "private static final class BlockingStub implements BlockingInterface " + "{\n"); + printer->Indent(); + + printer->Print( + "private BlockingStub(com.google.protobuf.BlockingRpcChannel channel) {\n" + " this.channel = channel;\n" + "}\n" + "\n" + "private final com.google.protobuf.BlockingRpcChannel channel;\n"); + + for (int i = 0; i < descriptor_->method_count(); i++) { + const MethodDescriptor* method = descriptor_->method(i); + GenerateBlockingMethodSignature(printer, method); + printer->Print(" {\n"); + printer->Indent(); + + std::map<std::string, std::string> vars; + vars["index"] = StrCat(i); + vars["output"] = GetOutput(method); + printer->Print(vars, + "return ($output$) channel.callBlockingMethod(\n" + " getDescriptor().getMethods().get($index$),\n" + " controller,\n" + " request,\n" + " $output$.getDefaultInstance());\n"); + + printer->Outdent(); + printer->Print( + "}\n" + "\n"); + } + + printer->Outdent(); + printer->Print("}\n"); +} + +void ImmutableServiceGenerator::GenerateMethodSignature( + io::Printer* printer, const MethodDescriptor* method, + IsAbstract is_abstract) { + std::map<std::string, std::string> vars; + vars["name"] = UnderscoresToCamelCase(method); + vars["input"] = name_resolver_->GetImmutableClassName(method->input_type()); + vars["output"] = GetOutput(method); + vars["abstract"] = (is_abstract == IS_ABSTRACT) ? "abstract" : ""; + printer->Print(vars, + "public $abstract$ void $name$(\n" + " com.google.protobuf.RpcController controller,\n" + " $input$ request,\n" + " com.google.protobuf.RpcCallback<$output$> done)"); +} + +void ImmutableServiceGenerator::GenerateBlockingMethodSignature( + io::Printer* printer, const MethodDescriptor* method) { + std::map<std::string, std::string> vars; + vars["method"] = UnderscoresToCamelCase(method); + vars["input"] = name_resolver_->GetImmutableClassName(method->input_type()); + vars["output"] = GetOutput(method); + printer->Print(vars, + "\n" + "public $output$ $method$(\n" + " com.google.protobuf.RpcController controller,\n" + " $input$ request)\n" + " throws com.google.protobuf.ServiceException"); +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_service.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_service.h new file mode 100644 index 00000000..f21d5f11 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_service.h @@ -0,0 +1,139 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_SERVICE_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_SERVICE_H__ + +#include <map> +#include <descriptor.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { +class Context; // context.h +class ClassNameResolver; // name_resolver.h +} // namespace java +} // namespace compiler +namespace io { +class Printer; // printer.h +} +} // namespace protobuf +} // namespace google + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +class ServiceGenerator { + public: + explicit ServiceGenerator(const ServiceDescriptor* descriptor); + virtual ~ServiceGenerator(); + + virtual void Generate(io::Printer* printer) = 0; + + enum RequestOrResponse { REQUEST, RESPONSE }; + enum IsAbstract { IS_ABSTRACT, IS_CONCRETE }; + + protected: + const ServiceDescriptor* descriptor_; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ServiceGenerator); +}; + +class ImmutableServiceGenerator : public ServiceGenerator { + public: + ImmutableServiceGenerator(const ServiceDescriptor* descriptor, + Context* context); + virtual ~ImmutableServiceGenerator(); + + void Generate(io::Printer* printer) override; + + private: + // Generate the getDescriptorForType() method. + void GenerateGetDescriptorForType(io::Printer* printer); + + // Generate a Java interface for the service. + void GenerateInterface(io::Printer* printer); + + // Generate newReflectiveService() method. + void GenerateNewReflectiveServiceMethod(io::Printer* printer); + + // Generate newReflectiveBlockingService() method. + void GenerateNewReflectiveBlockingServiceMethod(io::Printer* printer); + + // Generate abstract method declarations for all methods. + void GenerateAbstractMethods(io::Printer* printer); + + // Generate the implementation of Service.callMethod(). + void GenerateCallMethod(io::Printer* printer); + + // Generate the implementation of BlockingService.callBlockingMethod(). + void GenerateCallBlockingMethod(io::Printer* printer); + + // Generate the implementations of Service.get{Request,Response}Prototype(). + void GenerateGetPrototype(RequestOrResponse which, io::Printer* printer); + + // Generate a stub implementation of the service. + void GenerateStub(io::Printer* printer); + + // Generate a method signature, possibly abstract, without body or trailing + // semicolon. + void GenerateMethodSignature(io::Printer* printer, + const MethodDescriptor* method, + IsAbstract is_abstract); + + // Generate a blocking stub interface and implementation of the service. + void GenerateBlockingStub(io::Printer* printer); + + // Generate the method signature for one method of a blocking stub. + void GenerateBlockingMethodSignature(io::Printer* printer, + const MethodDescriptor* method); + + // Return the output type of the method. + std::string GetOutput(const MethodDescriptor* method); + + Context* context_; + ClassNameResolver* name_resolver_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableServiceGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // NET_PROTO2_COMPILER_JAVA_SERVICE_H__ diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_shared_code_generator.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_shared_code_generator.cc new file mode 100644 index 00000000..935ce7bb --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_shared_code_generator.cc @@ -0,0 +1,198 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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: xiaofeng@google.com (Feng Xiao) + +#include <compiler/java/java_shared_code_generator.h> + +#include <memory> + +#include <compiler/java/java_helpers.h> +#include <compiler/java/java_name_resolver.h> +#include <compiler/java/java_names.h> +#include <compiler/code_generator.h> +#include <descriptor.pb.h> +#include <io/printer.h> +#include <io/zero_copy_stream.h> +#include <descriptor.h> +#include <stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +SharedCodeGenerator::SharedCodeGenerator(const FileDescriptor* file, + const Options& options) + : name_resolver_(new ClassNameResolver), file_(file), options_(options) {} + +SharedCodeGenerator::~SharedCodeGenerator() {} + +void SharedCodeGenerator::Generate( + GeneratorContext* context, std::vector<std::string>* file_list, + std::vector<std::string>* annotation_file_list) { + std::string java_package = FileJavaPackage(file_); + std::string package_dir = JavaPackageToDir(java_package); + + if (HasDescriptorMethods(file_, options_.enforce_lite)) { + // Generate descriptors. + std::string classname = name_resolver_->GetDescriptorClassName(file_); + std::string filename = package_dir + classname + ".java"; + file_list->push_back(filename); + std::unique_ptr<io::ZeroCopyOutputStream> output(context->Open(filename)); + GeneratedCodeInfo annotations; + io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector( + &annotations); + std::unique_ptr<io::Printer> printer( + new io::Printer(output.get(), '$', + options_.annotate_code ? &annotation_collector : NULL)); + std::string info_relative_path = classname + ".java.pb.meta"; + std::string info_full_path = filename + ".pb.meta"; + printer->Print( + "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" + "// source: $filename$\n" + "\n", + "filename", file_->name()); + if (!java_package.empty()) { + printer->Print( + "package $package$;\n" + "\n", + "package", java_package); + } + PrintGeneratedAnnotation(printer.get(), '$', + options_.annotate_code ? info_relative_path : ""); + printer->Print( + "public final class $classname$ {\n" + " public static com.google.protobuf.Descriptors.FileDescriptor\n" + " descriptor;\n" + " static {\n", + "classname", classname); + printer->Annotate("classname", file_->name()); + printer->Indent(); + printer->Indent(); + GenerateDescriptors(printer.get()); + printer->Outdent(); + printer->Outdent(); + printer->Print( + " }\n" + "}\n"); + + if (options_.annotate_code) { + std::unique_ptr<io::ZeroCopyOutputStream> info_output( + context->Open(info_full_path)); + annotations.SerializeToZeroCopyStream(info_output.get()); + annotation_file_list->push_back(info_full_path); + } + + printer.reset(); + output.reset(); + } +} + +void SharedCodeGenerator::GenerateDescriptors(io::Printer* printer) { + // Embed the descriptor. We simply serialize the entire FileDescriptorProto + // and embed it as a string literal, which is parsed and built into real + // descriptors at initialization time. We unfortunately have to put it in + // a string literal, not a byte array, because apparently using a literal + // byte array causes the Java compiler to generate *instructions* to + // initialize each and every byte of the array, e.g. as if you typed: + // b[0] = 123; b[1] = 456; b[2] = 789; + // This makes huge bytecode files and can easily hit the compiler's internal + // code size limits (error "code to large"). String literals are apparently + // embedded raw, which is what we want. + FileDescriptorProto file_proto; + file_->CopyTo(&file_proto); + + std::string file_data; + file_proto.SerializeToString(&file_data); + + printer->Print("java.lang.String[] descriptorData = {\n"); + printer->Indent(); + + // Limit the number of bytes per line. + static const int kBytesPerLine = 40; + // Limit the number of lines per string part. + static const int kLinesPerPart = 400; + // Every block of bytes, start a new string literal, in order to avoid the + // 64k length limit. Note that this value needs to be <64k. + static const int kBytesPerPart = kBytesPerLine * kLinesPerPart; + for (int i = 0; i < file_data.size(); i += kBytesPerLine) { + if (i > 0) { + if (i % kBytesPerPart == 0) { + printer->Print(",\n"); + } else { + printer->Print(" +\n"); + } + } + printer->Print("\"$data$\"", "data", + CEscape(file_data.substr(i, kBytesPerLine))); + } + + printer->Outdent(); + printer->Print("\n};\n"); + + // ----------------------------------------------------------------- + // Find out all dependencies. + std::vector<std::pair<std::string, std::string> > dependencies; + for (int i = 0; i < file_->dependency_count(); i++) { + std::string filename = file_->dependency(i)->name(); + std::string package = FileJavaPackage(file_->dependency(i)); + std::string classname = + name_resolver_->GetDescriptorClassName(file_->dependency(i)); + std::string full_name; + if (package.empty()) { + full_name = classname; + } else { + full_name = package + "." + classname; + } + dependencies.push_back(std::make_pair(filename, full_name)); + } + + // ----------------------------------------------------------------- + // Invoke internalBuildGeneratedFileFrom() to build the file. + printer->Print( + "descriptor = com.google.protobuf.Descriptors.FileDescriptor\n" + " .internalBuildGeneratedFileFrom(descriptorData,\n"); + printer->Print( + " new com.google.protobuf.Descriptors.FileDescriptor[] {\n"); + + for (int i = 0; i < dependencies.size(); i++) { + const std::string& dependency = dependencies[i].second; + printer->Print(" $dependency$.getDescriptor(),\n", "dependency", + dependency); + } + + printer->Print(" });\n"); +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_shared_code_generator.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_shared_code_generator.h new file mode 100644 index 00000000..1e315863 --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_shared_code_generator.h @@ -0,0 +1,90 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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: xiaofeng@google.com (Feng Xiao) +// +// Generators that generate shared code between immutable API and mutable API. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_SHARED_CODE_GENERATOR_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_SHARED_CODE_GENERATOR_H__ + +#include <memory> +#include <string> +#include <vector> + +#include <stubs/common.h> +#include <compiler/java/java_options.h> + +namespace google { +namespace protobuf { +class FileDescriptor; // descriptor.h +namespace compiler { +class GeneratorContext; // code_generator.h +namespace java { +class ClassNameResolver; // name_resolver.h +} +} // namespace compiler +namespace io { +class Printer; // printer.h +} +} // namespace protobuf +} // namespace google + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +// A generator that generates code that are shared between immutable API +// and mutable API. Currently only descriptors are shared. +class SharedCodeGenerator { + public: + SharedCodeGenerator(const FileDescriptor* file, const Options& options); + ~SharedCodeGenerator(); + + void Generate(GeneratorContext* generator_context, + std::vector<std::string>* file_list, + std::vector<std::string>* annotation_file_list); + + void GenerateDescriptors(io::Printer* printer); + + private: + std::unique_ptr<ClassNameResolver> name_resolver_; + const FileDescriptor* file_; + const Options options_; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SharedCodeGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_SHARED_CODE_GENERATOR_H__ diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_string_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_string_field.cc new file mode 100644 index 00000000..454148ca --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_string_field.cc @@ -0,0 +1,1190 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Author: jonp@google.com (Jon Perlow) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <compiler/java/java_string_field.h> + +#include <cstdint> +#include <map> +#include <string> + +#include <stubs/logging.h> +#include <stubs/common.h> +#include <compiler/java/java_context.h> +#include <compiler/java/java_doc_comment.h> +#include <compiler/java/java_helpers.h> +#include <compiler/java/java_name_resolver.h> +#include <io/printer.h> +#include <wire_format.h> +#include <stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +using internal::WireFormat; +using internal::WireFormatLite; + +namespace { + +void SetPrimitiveVariables(const FieldDescriptor* descriptor, + int messageBitIndex, int builderBitIndex, + const FieldGeneratorInfo* info, + ClassNameResolver* name_resolver, + std::map<std::string, std::string>* variables) { + SetCommonFieldVariables(descriptor, info, variables); + + (*variables)["empty_list"] = "com.google.protobuf.LazyStringArrayList.EMPTY"; + + (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver); + (*variables)["default_init"] = + "= " + ImmutableDefaultValue(descriptor, name_resolver); + (*variables)["capitalized_type"] = "String"; + (*variables)["tag"] = + StrCat(static_cast<int32_t>(WireFormat::MakeTag(descriptor))); + (*variables)["tag_size"] = StrCat( + WireFormat::TagSize(descriptor->number(), GetType(descriptor))); + (*variables)["null_check"] = + " if (value == null) {\n" + " throw new NullPointerException();\n" + " }\n"; + (*variables)["isStringEmpty"] = "com.google.protobuf.GeneratedMessage" + + GeneratedCodeVersionSuffix() + + ".isStringEmpty"; + (*variables)["writeString"] = "com.google.protobuf.GeneratedMessage" + + GeneratedCodeVersionSuffix() + ".writeString"; + (*variables)["computeStringSize"] = "com.google.protobuf.GeneratedMessage" + + GeneratedCodeVersionSuffix() + + ".computeStringSize"; + + // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported + // by the proto compiler + (*variables)["deprecation"] = + descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; + (*variables)["kt_deprecation"] = + descriptor->options().deprecated() + ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] + + " is deprecated\") " + : ""; + (*variables)["on_changed"] = "onChanged();"; + + if (HasHasbit(descriptor)) { + // For singular messages and builders, one bit is used for the hasField bit. + (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); + (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex); + + // Note that these have a trailing ";". + (*variables)["set_has_field_bit_message"] = + GenerateSetBit(messageBitIndex) + ";"; + (*variables)["set_has_field_bit_builder"] = + GenerateSetBit(builderBitIndex) + ";"; + (*variables)["clear_has_field_bit_builder"] = + GenerateClearBit(builderBitIndex) + ";"; + + (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex); + } else { + (*variables)["set_has_field_bit_message"] = ""; + (*variables)["set_has_field_bit_builder"] = ""; + (*variables)["clear_has_field_bit_builder"] = ""; + + (*variables)["is_field_present_message"] = + "!" + (*variables)["isStringEmpty"] + "(" + (*variables)["name"] + "_)"; + } + + // For repeated builders, one bit is used for whether the array is immutable. + (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex); + (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex); + (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex); + + // For repeated fields, one bit is used for whether the array is immutable + // in the parsing constructor. + (*variables)["get_mutable_bit_parser"] = + GenerateGetBitMutableLocal(builderBitIndex); + (*variables)["set_mutable_bit_parser"] = + GenerateSetBitMutableLocal(builderBitIndex); + + (*variables)["get_has_field_bit_from_local"] = + GenerateGetBitFromLocal(builderBitIndex); + (*variables)["set_has_field_bit_to_local"] = + GenerateSetBitToLocal(messageBitIndex); +} + +} // namespace + +// =================================================================== + +ImmutableStringFieldGenerator::ImmutableStringFieldGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, + Context* context) + : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) { + SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex, + context->GetFieldGeneratorInfo(descriptor), + name_resolver_, &variables_); +} + +ImmutableStringFieldGenerator::~ImmutableStringFieldGenerator() {} + +int ImmutableStringFieldGenerator::GetNumBitsForMessage() const { + return HasHasbit(descriptor_) ? 1 : 0; +} + +int ImmutableStringFieldGenerator::GetNumBitsForBuilder() const { + return GetNumBitsForMessage(); +} + +// A note about how strings are handled. This code used to just store a String +// in the Message. This had two issues: +// +// 1. It wouldn't roundtrip byte arrays that were not valid UTF-8 encoded +// strings, but rather fields that were raw bytes incorrectly marked +// as strings in the proto file. This is common because in the proto1 +// syntax, string was the way to indicate bytes and C++ engineers can +// easily make this mistake without affecting the C++ API. By converting to +// strings immediately, some java code might corrupt these byte arrays as +// it passes through a java server even if the field was never accessed by +// application code. +// +// 2. There's a performance hit to converting between bytes and strings and +// it many cases, the field is never even read by the application code. This +// avoids unnecessary conversions in the common use cases. +// +// So now, the field for String is maintained as an Object reference which can +// either store a String or a ByteString. The code uses an instanceof check +// to see which one it has and converts to the other one if needed. It remembers +// the last value requested (in a thread safe manner) as this is most likely +// the one needed next. The thread safety is such that if two threads both +// convert the field because the changes made by each thread were not visible to +// the other, they may cause a conversion to happen more times than would +// otherwise be necessary. This was deemed better than adding synchronization +// overhead. It will not cause any corruption issues or affect the behavior of +// the API. The instanceof check is also highly optimized in the JVM and we +// decided it was better to reduce the memory overhead by not having two +// separate fields but rather use dynamic type checking. +// +// For single fields, the logic for this is done inside the generated code. For +// repeated fields, the logic is done in LazyStringArrayList and +// UnmodifiableLazyStringList. +void ImmutableStringFieldGenerator::GenerateInterfaceMembers( + io::Printer* printer) const { + if (HasHazzer(descriptor_)) { + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print(variables_, + "$deprecation$boolean has$capitalized_name$();\n"); + } + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, + "$deprecation$java.lang.String get$capitalized_name$();\n"); + WriteFieldStringBytesAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, + "$deprecation$com.google.protobuf.ByteString\n" + " get$capitalized_name$Bytes();\n"); +} + +void ImmutableStringFieldGenerator::GenerateMembers( + io::Printer* printer) const { + printer->Print(variables_, "private volatile java.lang.Object $name$_;\n"); + PrintExtraFieldInfo(variables_, printer); + + if (HasHazzer(descriptor_)) { + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return $get_has_field_bit_message$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } + + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n" + " java.lang.Object ref = $name$_;\n" + " if (ref instanceof java.lang.String) {\n" + " return (java.lang.String) ref;\n" + " } else {\n" + " com.google.protobuf.ByteString bs = \n" + " (com.google.protobuf.ByteString) ref;\n" + " java.lang.String s = bs.toStringUtf8();\n"); + printer->Annotate("{", "}", descriptor_); + if (CheckUtf8(descriptor_)) { + printer->Print(variables_, " $name$_ = s;\n"); + } else { + printer->Print(variables_, + " if (bs.isValidUtf8()) {\n" + " $name$_ = s;\n" + " }\n"); + } + printer->Print(variables_, + " return s;\n" + " }\n" + "}\n"); + WriteFieldStringBytesAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public com.google.protobuf.ByteString\n" + " ${$get$capitalized_name$Bytes$}$() {\n" + " java.lang.Object ref = $name$_;\n" + " if (ref instanceof java.lang.String) {\n" + " com.google.protobuf.ByteString b = \n" + " com.google.protobuf.ByteString.copyFromUtf8(\n" + " (java.lang.String) ref);\n" + " $name$_ = b;\n" + " return b;\n" + " } else {\n" + " return (com.google.protobuf.ByteString) ref;\n" + " }\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +void ImmutableStringFieldGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + printer->Print(variables_, + "private java.lang.Object $name$_ $default_init$;\n"); + if (HasHazzer(descriptor_)) { + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print( + variables_, + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return $get_has_field_bit_builder$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } + + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print( + variables_, + "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n" + " java.lang.Object ref = $name$_;\n" + " if (!(ref instanceof java.lang.String)) {\n" + " com.google.protobuf.ByteString bs =\n" + " (com.google.protobuf.ByteString) ref;\n" + " java.lang.String s = bs.toStringUtf8();\n"); + printer->Annotate("{", "}", descriptor_); + if (CheckUtf8(descriptor_)) { + printer->Print(variables_, " $name$_ = s;\n"); + } else { + printer->Print(variables_, + " if (bs.isValidUtf8()) {\n" + " $name$_ = s;\n" + " }\n"); + } + printer->Print(variables_, + " return s;\n" + " } else {\n" + " return (java.lang.String) ref;\n" + " }\n" + "}\n"); + + WriteFieldStringBytesAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, + "$deprecation$public com.google.protobuf.ByteString\n" + " ${$get$capitalized_name$Bytes$}$() {\n" + " java.lang.Object ref = $name$_;\n" + " if (ref instanceof String) {\n" + " com.google.protobuf.ByteString b = \n" + " com.google.protobuf.ByteString.copyFromUtf8(\n" + " (java.lang.String) ref);\n" + " $name$_ = b;\n" + " return b;\n" + " } else {\n" + " return (com.google.protobuf.ByteString) ref;\n" + " }\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldAccessorDocComment(printer, descriptor_, SETTER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" + " java.lang.String value) {\n" + "$null_check$" + " $set_has_field_bit_builder$\n" + " $name$_ = value;\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ true); + printer->Print( + variables_, + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" + " $clear_has_field_bit_builder$\n"); + printer->Annotate("{", "}", descriptor_); + // The default value is not a simple literal so we want to avoid executing + // it multiple times. Instead, get the default out of the default instance. + printer->Print(variables_, + " $name$_ = getDefaultInstance().get$capitalized_name$();\n"); + printer->Print(variables_, + " $on_changed$\n" + " return this;\n" + "}\n"); + + WriteFieldStringBytesAccessorDocComment(printer, descriptor_, SETTER, + /* builder */ true); + printer->Print( + variables_, + "$deprecation$public Builder ${$set$capitalized_name$Bytes$}$(\n" + " com.google.protobuf.ByteString value) {\n" + "$null_check$"); + printer->Annotate("{", "}", descriptor_); + if (CheckUtf8(descriptor_)) { + printer->Print(variables_, " checkByteStringIsUtf8(value);\n"); + } + printer->Print(variables_, + " $set_has_field_bit_builder$\n" + " $name$_ = value;\n" + " $on_changed$\n" + " return this;\n" + "}\n"); +} + +void ImmutableStringFieldGenerator::GenerateKotlinDslMembers( + io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$kt_deprecation$public var $kt_name$: kotlin.String\n" + " @JvmName(\"${$get$kt_capitalized_name$$}$\")\n" + " get() = $kt_dsl_builder$.${$get$capitalized_name$$}$()\n" + " @JvmName(\"${$set$kt_capitalized_name$$}$\")\n" + " set(value) {\n" + " $kt_dsl_builder$.${$set$capitalized_name$$}$(value)\n" + " }\n"); + + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ false); + printer->Print(variables_, + "public fun ${$clear$kt_capitalized_name$$}$() {\n" + " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n" + "}\n"); + + if (HasHazzer(descriptor_)) { + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print( + variables_, + "public fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n" + " return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n" + "}\n"); + } +} + +void ImmutableStringFieldGenerator::GenerateFieldBuilderInitializationCode( + io::Printer* printer) const { + // noop for primitives +} + +void ImmutableStringFieldGenerator::GenerateInitializationCode( + io::Printer* printer) const { + printer->Print(variables_, "$name$_ = $default$;\n"); +} + +void ImmutableStringFieldGenerator::GenerateBuilderClearCode( + io::Printer* printer) const { + printer->Print(variables_, + "$name$_ = $default$;\n" + "$clear_has_field_bit_builder$\n"); +} + +void ImmutableStringFieldGenerator::GenerateMergingCode( + io::Printer* printer) const { + if (HasHazzer(descriptor_)) { + // Allow a slight breach of abstraction here in order to avoid forcing + // all string fields to Strings when copying fields from a Message. + printer->Print(variables_, + "if (other.has$capitalized_name$()) {\n" + " $set_has_field_bit_builder$\n" + " $name$_ = other.$name$_;\n" + " $on_changed$\n" + "}\n"); + } else { + printer->Print(variables_, + "if (!other.get$capitalized_name$().isEmpty()) {\n" + " $name$_ = other.$name$_;\n" + " $on_changed$\n" + "}\n"); + } +} + +void ImmutableStringFieldGenerator::GenerateBuildingCode( + io::Printer* printer) const { + if (HasHazzer(descriptor_)) { + printer->Print(variables_, + "if ($get_has_field_bit_from_local$) {\n" + " $set_has_field_bit_to_local$;\n" + "}\n"); + } + printer->Print(variables_, "result.$name$_ = $name$_;\n"); +} + +void ImmutableStringFieldGenerator::GenerateParsingCode( + io::Printer* printer) const { + if (CheckUtf8(descriptor_)) { + printer->Print(variables_, + "java.lang.String s = input.readStringRequireUtf8();\n" + "$set_has_field_bit_message$\n" + "$name$_ = s;\n"); + } else { + printer->Print(variables_, + "com.google.protobuf.ByteString bs = input.readBytes();\n" + "$set_has_field_bit_message$\n" + "$name$_ = bs;\n"); + } +} + +void ImmutableStringFieldGenerator::GenerateParsingDoneCode( + io::Printer* printer) const { + // noop for strings. +} + +void ImmutableStringFieldGenerator::GenerateSerializationCode( + io::Printer* printer) const { + printer->Print(variables_, + "if ($is_field_present_message$) {\n" + " $writeString$(output, $number$, $name$_);\n" + "}\n"); +} + +void ImmutableStringFieldGenerator::GenerateSerializedSizeCode( + io::Printer* printer) const { + printer->Print(variables_, + "if ($is_field_present_message$) {\n" + " size += $computeStringSize$($number$, $name$_);\n" + "}\n"); +} + +void ImmutableStringFieldGenerator::GenerateEqualsCode( + io::Printer* printer) const { + printer->Print(variables_, + "if (!get$capitalized_name$()\n" + " .equals(other.get$capitalized_name$())) return false;\n"); +} + +void ImmutableStringFieldGenerator::GenerateHashCode( + io::Printer* printer) const { + printer->Print(variables_, "hash = (37 * hash) + $constant_name$;\n"); + printer->Print(variables_, + "hash = (53 * hash) + get$capitalized_name$().hashCode();\n"); +} + +std::string ImmutableStringFieldGenerator::GetBoxedType() const { + return "java.lang.String"; +} + +// =================================================================== + +ImmutableStringOneofFieldGenerator::ImmutableStringOneofFieldGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, + Context* context) + : ImmutableStringFieldGenerator(descriptor, messageBitIndex, + builderBitIndex, context) { + const OneofGeneratorInfo* info = + context->GetOneofGeneratorInfo(descriptor->containing_oneof()); + SetCommonOneofVariables(descriptor, info, &variables_); +} + +ImmutableStringOneofFieldGenerator::~ImmutableStringOneofFieldGenerator() {} + +void ImmutableStringOneofFieldGenerator::GenerateMembers( + io::Printer* printer) const { + PrintExtraFieldInfo(variables_, printer); + GOOGLE_DCHECK(HasHazzer(descriptor_)); + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print(variables_, + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return $has_oneof_case_message$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print( + variables_, + "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n" + " java.lang.Object ref $default_init$;\n" + " if ($has_oneof_case_message$) {\n" + " ref = $oneof_name$_;\n" + " }\n" + " if (ref instanceof java.lang.String) {\n" + " return (java.lang.String) ref;\n" + " } else {\n" + " com.google.protobuf.ByteString bs = \n" + " (com.google.protobuf.ByteString) ref;\n" + " java.lang.String s = bs.toStringUtf8();\n"); + printer->Annotate("{", "}", descriptor_); + if (CheckUtf8(descriptor_)) { + printer->Print(variables_, + " if ($has_oneof_case_message$) {\n" + " $oneof_name$_ = s;\n" + " }\n"); + } else { + printer->Print(variables_, + " if (bs.isValidUtf8() && ($has_oneof_case_message$)) {\n" + " $oneof_name$_ = s;\n" + " }\n"); + } + printer->Print(variables_, + " return s;\n" + " }\n" + "}\n"); + WriteFieldStringBytesAccessorDocComment(printer, descriptor_, GETTER); + + printer->Print(variables_, + "$deprecation$public com.google.protobuf.ByteString\n" + " ${$get$capitalized_name$Bytes$}$() {\n" + " java.lang.Object ref $default_init$;\n" + " if ($has_oneof_case_message$) {\n" + " ref = $oneof_name$_;\n" + " }\n" + " if (ref instanceof java.lang.String) {\n" + " com.google.protobuf.ByteString b = \n" + " com.google.protobuf.ByteString.copyFromUtf8(\n" + " (java.lang.String) ref);\n" + " if ($has_oneof_case_message$) {\n" + " $oneof_name$_ = b;\n" + " }\n" + " return b;\n" + " } else {\n" + " return (com.google.protobuf.ByteString) ref;\n" + " }\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +void ImmutableStringOneofFieldGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + GOOGLE_DCHECK(HasHazzer(descriptor_)); + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return $has_oneof_case_message$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n" + " java.lang.Object ref $default_init$;\n" + " if ($has_oneof_case_message$) {\n" + " ref = $oneof_name$_;\n" + " }\n" + " if (!(ref instanceof java.lang.String)) {\n" + " com.google.protobuf.ByteString bs =\n" + " (com.google.protobuf.ByteString) ref;\n" + " java.lang.String s = bs.toStringUtf8();\n" + " if ($has_oneof_case_message$) {\n"); + printer->Annotate("{", "}", descriptor_); + if (CheckUtf8(descriptor_)) { + printer->Print(variables_, " $oneof_name$_ = s;\n"); + } else { + printer->Print(variables_, + " if (bs.isValidUtf8()) {\n" + " $oneof_name$_ = s;\n" + " }\n"); + } + printer->Print(variables_, + " }\n" + " return s;\n" + " } else {\n" + " return (java.lang.String) ref;\n" + " }\n" + "}\n"); + + WriteFieldStringBytesAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public com.google.protobuf.ByteString\n" + " ${$get$capitalized_name$Bytes$}$() {\n" + " java.lang.Object ref $default_init$;\n" + " if ($has_oneof_case_message$) {\n" + " ref = $oneof_name$_;\n" + " }\n" + " if (ref instanceof String) {\n" + " com.google.protobuf.ByteString b = \n" + " com.google.protobuf.ByteString.copyFromUtf8(\n" + " (java.lang.String) ref);\n" + " if ($has_oneof_case_message$) {\n" + " $oneof_name$_ = b;\n" + " }\n" + " return b;\n" + " } else {\n" + " return (com.google.protobuf.ByteString) ref;\n" + " }\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldAccessorDocComment(printer, descriptor_, SETTER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" + " java.lang.String value) {\n" + "$null_check$" + " $set_oneof_case_message$;\n" + " $oneof_name$_ = value;\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ true); + printer->Print( + variables_, + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" + " if ($has_oneof_case_message$) {\n" + " $clear_oneof_case_message$;\n" + " $oneof_name$_ = null;\n" + " $on_changed$\n" + " }\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldStringBytesAccessorDocComment(printer, descriptor_, SETTER, + /* builder */ true); + printer->Print( + variables_, + "$deprecation$public Builder ${$set$capitalized_name$Bytes$}$(\n" + " com.google.protobuf.ByteString value) {\n" + "$null_check$"); + printer->Annotate("{", "}", descriptor_); + if (CheckUtf8(descriptor_)) { + printer->Print(variables_, " checkByteStringIsUtf8(value);\n"); + } + printer->Print(variables_, + " $set_oneof_case_message$;\n" + " $oneof_name$_ = value;\n" + " $on_changed$\n" + " return this;\n" + "}\n"); +} + +void ImmutableStringOneofFieldGenerator::GenerateMergingCode( + io::Printer* printer) const { + // Allow a slight breach of abstraction here in order to avoid forcing + // all string fields to Strings when copying fields from a Message. + printer->Print(variables_, + "$set_oneof_case_message$;\n" + "$oneof_name$_ = other.$oneof_name$_;\n" + "$on_changed$\n"); +} + +void ImmutableStringOneofFieldGenerator::GenerateBuildingCode( + io::Printer* printer) const { + printer->Print(variables_, + "if ($has_oneof_case_message$) {\n" + " result.$oneof_name$_ = $oneof_name$_;\n" + "}\n"); +} + +void ImmutableStringOneofFieldGenerator::GenerateParsingCode( + io::Printer* printer) const { + if (CheckUtf8(descriptor_)) { + printer->Print(variables_, + "java.lang.String s = input.readStringRequireUtf8();\n" + "$set_oneof_case_message$;\n" + "$oneof_name$_ = s;\n"); + } else { + printer->Print(variables_, + "com.google.protobuf.ByteString bs = input.readBytes();\n" + "$set_oneof_case_message$;\n" + "$oneof_name$_ = bs;\n"); + } +} + +void ImmutableStringOneofFieldGenerator::GenerateSerializationCode( + io::Printer* printer) const { + printer->Print(variables_, + "if ($has_oneof_case_message$) {\n" + " $writeString$(output, $number$, $oneof_name$_);\n" + "}\n"); +} + +void ImmutableStringOneofFieldGenerator::GenerateSerializedSizeCode( + io::Printer* printer) const { + printer->Print(variables_, + "if ($has_oneof_case_message$) {\n" + " size += $computeStringSize$($number$, $oneof_name$_);\n" + "}\n"); +} + +// =================================================================== + +RepeatedImmutableStringFieldGenerator::RepeatedImmutableStringFieldGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex, + Context* context) + : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) { + SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex, + context->GetFieldGeneratorInfo(descriptor), + name_resolver_, &variables_); +} + +RepeatedImmutableStringFieldGenerator:: + ~RepeatedImmutableStringFieldGenerator() {} + +int RepeatedImmutableStringFieldGenerator::GetNumBitsForMessage() const { + return 0; +} + +int RepeatedImmutableStringFieldGenerator::GetNumBitsForBuilder() const { + return 1; +} + +void RepeatedImmutableStringFieldGenerator::GenerateInterfaceMembers( + io::Printer* printer) const { + WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER); + printer->Print( + variables_, + // NOTE: the same method in the implementation class actually returns + // com.google.protobuf.ProtocolStringList (a subclass of List). It's + // changed between protobuf 2.5.0 release and protobuf 2.6.1 release. + // To retain binary compatibility with both 2.5.0 and 2.6.1 generated + // code, we make this interface method return List so both methods + // with different return types exist in the compiled byte code. + "$deprecation$java.util.List<java.lang.String>\n" + " get$capitalized_name$List();\n"); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT); + printer->Print(variables_, + "$deprecation$int get$capitalized_name$Count();\n"); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER); + printer->Print( + variables_, + "$deprecation$java.lang.String get$capitalized_name$(int index);\n"); + WriteFieldStringBytesAccessorDocComment(printer, descriptor_, + LIST_INDEXED_GETTER); + printer->Print(variables_, + "$deprecation$com.google.protobuf.ByteString\n" + " get$capitalized_name$Bytes(int index);\n"); +} + +void RepeatedImmutableStringFieldGenerator::GenerateMembers( + io::Printer* printer) const { + printer->Print(variables_, + "private com.google.protobuf.LazyStringList $name$_;\n"); + PrintExtraFieldInfo(variables_, printer); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER); + printer->Print(variables_, + "$deprecation$public com.google.protobuf.ProtocolStringList\n" + " ${$get$capitalized_name$List$}$() {\n" + " return $name$_;\n" // note: unmodifiable list + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT); + printer->Print( + variables_, + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" + " return $name$_.size();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER); + printer->Print(variables_, + "$deprecation$public java.lang.String " + "${$get$capitalized_name$$}$(int index) {\n" + " return $name$_.get(index);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldStringBytesAccessorDocComment(printer, descriptor_, + LIST_INDEXED_GETTER); + printer->Print(variables_, + "$deprecation$public com.google.protobuf.ByteString\n" + " ${$get$capitalized_name$Bytes$}$(int index) {\n" + " return $name$_.getByteString(index);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +void RepeatedImmutableStringFieldGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + // One field is the list and the bit field keeps track of whether the + // list is immutable. If it's immutable, the invariant is that it must + // either an instance of Collections.emptyList() or it's an ArrayList + // wrapped in a Collections.unmodifiableList() wrapper and nobody else has + // a reference to the underlying ArrayList. This invariant allows us to + // share instances of lists between protocol buffers avoiding expensive + // memory allocations. Note, immutable is a strong guarantee here -- not + // just that the list cannot be modified via the reference but that the + // list can never be modified. + printer->Print( + variables_, + "private com.google.protobuf.LazyStringList $name$_ = $empty_list$;\n"); + + printer->Print( + variables_, + "private void ensure$capitalized_name$IsMutable() {\n" + " if (!$get_mutable_bit_builder$) {\n" + " $name$_ = new com.google.protobuf.LazyStringArrayList($name$_);\n" + " $set_mutable_bit_builder$;\n" + " }\n" + "}\n"); + + // Note: We return an unmodifiable list because otherwise the caller + // could hold on to the returned list and modify it after the message + // has been built, thus mutating the message which is supposed to be + // immutable. + WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER); + printer->Print(variables_, + "$deprecation$public com.google.protobuf.ProtocolStringList\n" + " ${$get$capitalized_name$List$}$() {\n" + " return $name$_.getUnmodifiableView();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT); + printer->Print( + variables_, + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" + " return $name$_.size();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER); + printer->Print(variables_, + "$deprecation$public java.lang.String " + "${$get$capitalized_name$$}$(int index) {\n" + " return $name$_.get(index);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldStringBytesAccessorDocComment(printer, descriptor_, + LIST_INDEXED_GETTER); + printer->Print(variables_, + "$deprecation$public com.google.protobuf.ByteString\n" + " ${$get$capitalized_name$Bytes$}$(int index) {\n" + " return $name$_.getByteString(index);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" + " int index, java.lang.String value) {\n" + "$null_check$" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.set(index, value);\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder ${$add$capitalized_name$$}$(\n" + " java.lang.String value) {\n" + "$null_check$" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.add(value);\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n" + " java.lang.Iterable<java.lang.String> values) {\n" + " ensure$capitalized_name$IsMutable();\n" + " com.google.protobuf.AbstractMessageLite.Builder.addAll(\n" + " values, $name$_);\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ true); + printer->Print( + variables_, + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" + " $name$_ = $empty_list$;\n" + " $clear_mutable_bit_builder$;\n" + " $on_changed$\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldStringBytesAccessorDocComment(printer, descriptor_, LIST_ADDER, + /* builder */ true); + printer->Print( + variables_, + "$deprecation$public Builder ${$add$capitalized_name$Bytes$}$(\n" + " com.google.protobuf.ByteString value) {\n" + "$null_check$"); + printer->Annotate("{", "}", descriptor_); + if (CheckUtf8(descriptor_)) { + printer->Print(variables_, " checkByteStringIsUtf8(value);\n"); + } + printer->Print(variables_, + " ensure$capitalized_name$IsMutable();\n" + " $name$_.add(value);\n" + " $on_changed$\n" + " return this;\n" + "}\n"); +} + +void RepeatedImmutableStringFieldGenerator::GenerateKotlinDslMembers( + io::Printer* printer) const { + printer->Print( + variables_, + "/**\n" + " * An uninstantiable, behaviorless type to represent the field in\n" + " * generics.\n" + " */\n" + "@kotlin.OptIn" + "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n" + "public class ${$$kt_capitalized_name$Proxy$}$ private constructor()" + " : com.google.protobuf.kotlin.DslProxy()\n"); + + // property for List<String> + WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER); + printer->Print(variables_, + "$kt_deprecation$public val $kt_name$: " + "com.google.protobuf.kotlin.DslList" + "<kotlin.String, ${$$kt_capitalized_name$Proxy$}$>\n" + " @kotlin.jvm.JvmSynthetic\n" + " get() = com.google.protobuf.kotlin.DslList(\n" + " $kt_dsl_builder$.${$get$capitalized_name$List$}$()\n" + " )\n"); + + // List<String>.add(String) + WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, + /* builder */ false); + printer->Print(variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"add$kt_capitalized_name$\")\n" + "public fun com.google.protobuf.kotlin.DslList" + "<kotlin.String, ${$$kt_capitalized_name$Proxy$}$>." + "add(value: kotlin.String) {\n" + " $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n" + "}\n"); + + // List<String> += String + WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, + /* builder */ false); + printer->Print(variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"plusAssign$kt_capitalized_name$\")\n" + "@Suppress(\"NOTHING_TO_INLINE\")\n" + "public inline operator fun com.google.protobuf.kotlin.DslList" + "<kotlin.String, ${$$kt_capitalized_name$Proxy$}$>." + "plusAssign(value: kotlin.String) {\n" + " add(value)\n" + "}\n"); + + // List<String>.addAll(Iterable<String>) + WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, + /* builder */ false); + printer->Print( + variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"addAll$kt_capitalized_name$\")\n" + "public fun com.google.protobuf.kotlin.DslList" + "<kotlin.String, ${$$kt_capitalized_name$Proxy$}$>." + "addAll(values: kotlin.collections.Iterable<kotlin.String>) {\n" + " $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n" + "}\n"); + + // List<String> += Iterable<String> + WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, + /* builder */ false); + printer->Print( + variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"plusAssignAll$kt_capitalized_name$\")\n" + "@Suppress(\"NOTHING_TO_INLINE\")\n" + "public inline operator fun com.google.protobuf.kotlin.DslList" + "<kotlin.String, ${$$kt_capitalized_name$Proxy$}$>." + "plusAssign(values: kotlin.collections.Iterable<kotlin.String>) {\n" + " addAll(values)\n" + "}\n"); + + // List<String>[Int] = String + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER, + /* builder */ false); + printer->Print( + variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"set$kt_capitalized_name$\")\n" + "public operator fun com.google.protobuf.kotlin.DslList" + "<kotlin.String, ${$$kt_capitalized_name$Proxy$}$>." + "set(index: kotlin.Int, value: kotlin.String) {\n" + " $kt_dsl_builder$.${$set$capitalized_name$$}$(index, value)\n" + "}"); + + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ false); + printer->Print(variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"clear$kt_capitalized_name$\")\n" + "public fun com.google.protobuf.kotlin.DslList" + "<kotlin.String, ${$$kt_capitalized_name$Proxy$}$>." + "clear() {\n" + " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n" + "}"); +} + +void RepeatedImmutableStringFieldGenerator:: + GenerateFieldBuilderInitializationCode(io::Printer* printer) const { + // noop for primitives +} + +void RepeatedImmutableStringFieldGenerator::GenerateInitializationCode( + io::Printer* printer) const { + printer->Print(variables_, "$name$_ = $empty_list$;\n"); +} + +void RepeatedImmutableStringFieldGenerator::GenerateBuilderClearCode( + io::Printer* printer) const { + printer->Print(variables_, + "$name$_ = $empty_list$;\n" + "$clear_mutable_bit_builder$;\n"); +} + +void RepeatedImmutableStringFieldGenerator::GenerateMergingCode( + io::Printer* printer) const { + // The code below does two optimizations: + // 1. If the other list is empty, there's nothing to do. This ensures we + // don't allocate a new array if we already have an immutable one. + // 2. If the other list is non-empty and our current list is empty, we can + // reuse the other list which is guaranteed to be immutable. + printer->Print(variables_, + "if (!other.$name$_.isEmpty()) {\n" + " if ($name$_.isEmpty()) {\n" + " $name$_ = other.$name$_;\n" + " $clear_mutable_bit_builder$;\n" + " } else {\n" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.addAll(other.$name$_);\n" + " }\n" + " $on_changed$\n" + "}\n"); +} + +void RepeatedImmutableStringFieldGenerator::GenerateBuildingCode( + io::Printer* printer) const { + // The code below ensures that the result has an immutable list. If our + // list is immutable, we can just reuse it. If not, we make it immutable. + + printer->Print(variables_, + "if ($get_mutable_bit_builder$) {\n" + " $name$_ = $name$_.getUnmodifiableView();\n" + " $clear_mutable_bit_builder$;\n" + "}\n" + "result.$name$_ = $name$_;\n"); +} + +void RepeatedImmutableStringFieldGenerator::GenerateParsingCode( + io::Printer* printer) const { + if (CheckUtf8(descriptor_)) { + printer->Print(variables_, + "java.lang.String s = input.readStringRequireUtf8();\n"); + } else { + printer->Print(variables_, + "com.google.protobuf.ByteString bs = input.readBytes();\n"); + } + printer->Print(variables_, + "if (!$get_mutable_bit_parser$) {\n" + " $name$_ = new com.google.protobuf.LazyStringArrayList();\n" + " $set_mutable_bit_parser$;\n" + "}\n"); + if (CheckUtf8(descriptor_)) { + printer->Print(variables_, "$name$_.add(s);\n"); + } else { + printer->Print(variables_, "$name$_.add(bs);\n"); + } +} + +void RepeatedImmutableStringFieldGenerator::GenerateParsingDoneCode( + io::Printer* printer) const { + printer->Print(variables_, + "if ($get_mutable_bit_parser$) {\n" + " $name$_ = $name$_.getUnmodifiableView();\n" + "}\n"); +} + +void RepeatedImmutableStringFieldGenerator::GenerateSerializationCode( + io::Printer* printer) const { + printer->Print(variables_, + "for (int i = 0; i < $name$_.size(); i++) {\n" + " $writeString$(output, $number$, $name$_.getRaw(i));\n" + "}\n"); +} + +void RepeatedImmutableStringFieldGenerator::GenerateSerializedSizeCode( + io::Printer* printer) const { + printer->Print(variables_, + "{\n" + " int dataSize = 0;\n"); + printer->Indent(); + + printer->Print(variables_, + "for (int i = 0; i < $name$_.size(); i++) {\n" + " dataSize += computeStringSizeNoTag($name$_.getRaw(i));\n" + "}\n"); + + printer->Print("size += dataSize;\n"); + + printer->Print(variables_, + "size += $tag_size$ * get$capitalized_name$List().size();\n"); + + printer->Outdent(); + printer->Print("}\n"); +} + +void RepeatedImmutableStringFieldGenerator::GenerateEqualsCode( + io::Printer* printer) const { + printer->Print( + variables_, + "if (!get$capitalized_name$List()\n" + " .equals(other.get$capitalized_name$List())) return false;\n"); +} + +void RepeatedImmutableStringFieldGenerator::GenerateHashCode( + io::Printer* printer) const { + printer->Print( + variables_, + "if (get$capitalized_name$Count() > 0) {\n" + " hash = (37 * hash) + $constant_name$;\n" + " hash = (53 * hash) + get$capitalized_name$List().hashCode();\n" + "}\n"); +} + +std::string RepeatedImmutableStringFieldGenerator::GetBoxedType() const { + return "String"; +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_string_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_string_field.h new file mode 100644 index 00000000..03fd43ec --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_string_field.h @@ -0,0 +1,160 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Author: jonp@google.com (Jon Perlow) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_STRING_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_STRING_FIELD_H__ + +#include <map> +#include <string> +#include <compiler/java/java_field.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { +class Context; // context.h +class ClassNameResolver; // name_resolver.h +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +class ImmutableStringFieldGenerator : public ImmutableFieldGenerator { + public: + explicit ImmutableStringFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + int builderBitIndex, Context* context); + ~ImmutableStringFieldGenerator(); + + // implements ImmutableFieldGenerator + // --------------------------------------- + int GetNumBitsForMessage() const override; + int GetNumBitsForBuilder() const override; + void GenerateInterfaceMembers(io::Printer* printer) const override; + void GenerateMembers(io::Printer* printer) const override; + void GenerateBuilderMembers(io::Printer* printer) const override; + void GenerateInitializationCode(io::Printer* printer) const override; + void GenerateBuilderClearCode(io::Printer* printer) const override; + void GenerateMergingCode(io::Printer* printer) const override; + void GenerateBuildingCode(io::Printer* printer) const override; + void GenerateParsingCode(io::Printer* printer) const override; + void GenerateParsingDoneCode(io::Printer* printer) const override; + void GenerateSerializationCode(io::Printer* printer) const override; + void GenerateSerializedSizeCode(io::Printer* printer) const override; + void GenerateFieldBuilderInitializationCode( + io::Printer* printer) const override; + void GenerateEqualsCode(io::Printer* printer) const override; + void GenerateHashCode(io::Printer* printer) const override; + void GenerateKotlinDslMembers(io::Printer* printer) const override; + + std::string GetBoxedType() const override; + + protected: + const FieldDescriptor* descriptor_; + std::map<std::string, std::string> variables_; + ClassNameResolver* name_resolver_; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableStringFieldGenerator); +}; + +class ImmutableStringOneofFieldGenerator + : public ImmutableStringFieldGenerator { + public: + ImmutableStringOneofFieldGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, int builderBitIndex, + Context* context); + ~ImmutableStringOneofFieldGenerator(); + + private: + void GenerateMembers(io::Printer* printer) const override; + void GenerateBuilderMembers(io::Printer* printer) const override; + void GenerateMergingCode(io::Printer* printer) const override; + void GenerateBuildingCode(io::Printer* printer) const override; + void GenerateParsingCode(io::Printer* printer) const override; + void GenerateSerializationCode(io::Printer* printer) const override; + void GenerateSerializedSizeCode(io::Printer* printer) const override; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableStringOneofFieldGenerator); +}; + +class RepeatedImmutableStringFieldGenerator : public ImmutableFieldGenerator { + public: + explicit RepeatedImmutableStringFieldGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, + int builderBitIndex, Context* context); + ~RepeatedImmutableStringFieldGenerator() override; + + // implements ImmutableFieldGenerator --------------------------------------- + int GetNumBitsForMessage() const override; + int GetNumBitsForBuilder() const override; + void GenerateInterfaceMembers(io::Printer* printer) const override; + void GenerateMembers(io::Printer* printer) const override; + void GenerateBuilderMembers(io::Printer* printer) const override; + void GenerateInitializationCode(io::Printer* printer) const override; + void GenerateBuilderClearCode(io::Printer* printer) const override; + void GenerateMergingCode(io::Printer* printer) const override; + void GenerateBuildingCode(io::Printer* printer) const override; + void GenerateParsingCode(io::Printer* printer) const override; + void GenerateParsingDoneCode(io::Printer* printer) const override; + void GenerateSerializationCode(io::Printer* printer) const override; + void GenerateSerializedSizeCode(io::Printer* printer) const override; + void GenerateFieldBuilderInitializationCode( + io::Printer* printer) const override; + void GenerateEqualsCode(io::Printer* printer) const override; + void GenerateHashCode(io::Printer* printer) const override; + void GenerateKotlinDslMembers(io::Printer* printer) const override; + + std::string GetBoxedType() const override; + + private: + const FieldDescriptor* descriptor_; + std::map<std::string, std::string> variables_; + ClassNameResolver* name_resolver_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableStringFieldGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_STRING_FIELD_H__ diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_string_field_lite.cc b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_string_field_lite.cc new file mode 100644 index 00000000..6f52fd8f --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_string_field_lite.cc @@ -0,0 +1,864 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Author: jonp@google.com (Jon Perlow) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#include <compiler/java/java_string_field_lite.h> + +#include <cstdint> +#include <map> +#include <string> + +#include <stubs/logging.h> +#include <stubs/common.h> +#include <compiler/java/java_context.h> +#include <compiler/java/java_doc_comment.h> +#include <compiler/java/java_helpers.h> +#include <compiler/java/java_name_resolver.h> +#include <io/printer.h> +#include <wire_format.h> +#include <stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +using internal::WireFormat; +using internal::WireFormatLite; + +namespace { + +void SetPrimitiveVariables(const FieldDescriptor* descriptor, + int messageBitIndex, int builderBitIndex, + const FieldGeneratorInfo* info, + ClassNameResolver* name_resolver, + std::map<std::string, std::string>* variables) { + SetCommonFieldVariables(descriptor, info, variables); + + (*variables)["empty_list"] = + "com.google.protobuf.GeneratedMessageLite.emptyProtobufList()"; + + (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver); + (*variables)["default_init"] = + "= " + ImmutableDefaultValue(descriptor, name_resolver); + (*variables)["capitalized_type"] = "java.lang.String"; + (*variables)["tag"] = + StrCat(static_cast<int32_t>(WireFormat::MakeTag(descriptor))); + (*variables)["tag_size"] = StrCat( + WireFormat::TagSize(descriptor->number(), GetType(descriptor))); + // We use `x.getClass()` as a null check because it generates less bytecode + // than an `if (x == null) { throw ... }` statement. + (*variables)["null_check"] = + " java.lang.Class<?> valueClass = value.getClass();\n"; + + // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported + // by the proto compiler + (*variables)["deprecation"] = + descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; + (*variables)["kt_deprecation"] = + descriptor->options().deprecated() + ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] + + " is deprecated\") " + : ""; + (*variables)["required"] = descriptor->is_required() ? "true" : "false"; + + if (HasHasbit(descriptor)) { + // For singular messages and builders, one bit is used for the hasField bit. + (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); + + // Note that these have a trailing ";". + (*variables)["set_has_field_bit_message"] = + GenerateSetBit(messageBitIndex) + ";"; + (*variables)["clear_has_field_bit_message"] = + GenerateClearBit(messageBitIndex) + ";"; + + (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex); + } else { + (*variables)["set_has_field_bit_message"] = ""; + (*variables)["clear_has_field_bit_message"] = ""; + + (*variables)["is_field_present_message"] = + "!" + (*variables)["name"] + "_.isEmpty()"; + } + + (*variables)["get_has_field_bit_from_local"] = + GenerateGetBitFromLocal(builderBitIndex); + (*variables)["set_has_field_bit_to_local"] = + GenerateSetBitToLocal(messageBitIndex); +} + +} // namespace + +// =================================================================== + +ImmutableStringFieldLiteGenerator::ImmutableStringFieldLiteGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, Context* context) + : descriptor_(descriptor), + messageBitIndex_(messageBitIndex), + name_resolver_(context->GetNameResolver()) { + SetPrimitiveVariables(descriptor, messageBitIndex, 0, + context->GetFieldGeneratorInfo(descriptor), + name_resolver_, &variables_); +} + +ImmutableStringFieldLiteGenerator::~ImmutableStringFieldLiteGenerator() {} + +int ImmutableStringFieldLiteGenerator::GetNumBitsForMessage() const { + return HasHasbit(descriptor_) ? 1 : 0; +} + +// A note about how strings are handled. In the SPEED and CODE_SIZE runtimes, +// strings are not stored as java.lang.String in the Message because of two +// issues: +// +// 1. It wouldn't roundtrip byte arrays that were not valid UTF-8 encoded +// strings, but rather fields that were raw bytes incorrectly marked +// as strings in the proto file. This is common because in the proto1 +// syntax, string was the way to indicate bytes and C++ engineers can +// easily make this mistake without affecting the C++ API. By converting to +// strings immediately, some java code might corrupt these byte arrays as +// it passes through a java server even if the field was never accessed by +// application code. +// +// 2. There's a performance hit to converting between bytes and strings and +// it many cases, the field is never even read by the application code. This +// avoids unnecessary conversions in the common use cases. +// +// In the LITE_RUNTIME, we store strings as java.lang.String because we assume +// that the users of this runtime are not subject to proto1 constraints and are +// running code on devices that are user facing. That is, the developers are +// properly incentivized to only fetch the data they need to read and wish to +// reduce the number of allocations incurred when running on a user's device. + +// TODO(dweis): Consider dropping all of the *Bytes() methods. They really +// shouldn't be necessary or used on devices. +void ImmutableStringFieldLiteGenerator::GenerateInterfaceMembers( + io::Printer* printer) const { + if (HasHazzer(descriptor_)) { + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print(variables_, + "$deprecation$boolean has$capitalized_name$();\n"); + } + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, + "$deprecation$java.lang.String get$capitalized_name$();\n"); + WriteFieldStringBytesAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, + "$deprecation$com.google.protobuf.ByteString\n" + " get$capitalized_name$Bytes();\n"); +} + +void ImmutableStringFieldLiteGenerator::GenerateMembers( + io::Printer* printer) const { + printer->Print(variables_, "private java.lang.String $name$_;\n"); + PrintExtraFieldInfo(variables_, printer); + + if (HasHazzer(descriptor_)) { + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return $get_has_field_bit_message$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } + + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n" + " return $name$_;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldStringBytesAccessorDocComment(printer, descriptor_, GETTER); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public com.google.protobuf.ByteString\n" + " ${$get$capitalized_name$Bytes$}$() {\n" + " return com.google.protobuf.ByteString.copyFromUtf8($name$_);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldAccessorDocComment(printer, descriptor_, SETTER); + printer->Print(variables_, + "private void set$capitalized_name$(\n" + " java.lang.String value) {\n" + "$null_check$" + " $set_has_field_bit_message$\n" + " $name$_ = value;\n" + "}\n"); + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER); + printer->Print(variables_, + "private void clear$capitalized_name$() {\n" + " $clear_has_field_bit_message$\n" + // The default value is not a simple literal so we want to + // avoid executing it multiple times. Instead, get the default + // out of the default instance. + " $name$_ = getDefaultInstance().get$capitalized_name$();\n" + "}\n"); + + WriteFieldStringBytesAccessorDocComment(printer, descriptor_, SETTER); + printer->Print(variables_, + "private void set$capitalized_name$Bytes(\n" + " com.google.protobuf.ByteString value) {\n"); + if (CheckUtf8(descriptor_)) { + printer->Print(variables_, " checkByteStringIsUtf8(value);\n"); + } + printer->Print(variables_, + " $name$_ = value.toStringUtf8();\n" + " $set_has_field_bit_message$\n" + "}\n"); +} + +void ImmutableStringFieldLiteGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + if (HasHazzer(descriptor_)) { + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return instance.has$capitalized_name$();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + } + + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n" + " return instance.get$capitalized_name$();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldStringBytesAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public com.google.protobuf.ByteString\n" + " ${$get$capitalized_name$Bytes$}$() {\n" + " return instance.get$capitalized_name$Bytes();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldAccessorDocComment(printer, descriptor_, SETTER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" + " java.lang.String value) {\n" + " copyOnWrite();\n" + " instance.set$capitalized_name$(value);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ true); + printer->Print( + variables_, + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" + " copyOnWrite();\n" + " instance.clear$capitalized_name$();\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldStringBytesAccessorDocComment(printer, descriptor_, SETTER, + /* builder */ true); + printer->Print( + variables_, + "$deprecation$public Builder ${$set$capitalized_name$Bytes$}$(\n" + " com.google.protobuf.ByteString value) {\n" + " copyOnWrite();\n" + " instance.set$capitalized_name$Bytes(value);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +void ImmutableStringFieldLiteGenerator::GenerateKotlinDslMembers( + io::Printer* printer) const { + WriteFieldDocComment(printer, descriptor_); + printer->Print(variables_, + "$kt_deprecation$public var $kt_name$: kotlin.String\n" + " @JvmName(\"${$get$kt_capitalized_name$$}$\")\n" + " get() = $kt_dsl_builder$.${$get$capitalized_name$$}$()\n" + " @JvmName(\"${$set$kt_capitalized_name$$}$\")\n" + " set(value) {\n" + " $kt_dsl_builder$.${$set$capitalized_name$$}$(value)\n" + " }\n"); + + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ false); + printer->Print(variables_, + "public fun ${$clear$kt_capitalized_name$$}$() {\n" + " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n" + "}\n"); + + if (HasHazzer(descriptor_)) { + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print( + variables_, + "public fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n" + " return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n" + "}\n"); + } +} + +void ImmutableStringFieldLiteGenerator::GenerateFieldInfo( + io::Printer* printer, std::vector<uint16_t>* output) const { + WriteIntToUtf16CharSequence(descriptor_->number(), output); + WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_), + output); + if (HasHasbit(descriptor_)) { + WriteIntToUtf16CharSequence(messageBitIndex_, output); + } + printer->Print(variables_, "\"$name$_\",\n"); +} + +void ImmutableStringFieldLiteGenerator::GenerateInitializationCode( + io::Printer* printer) const { + printer->Print(variables_, "$name$_ = $default$;\n"); +} + +std::string ImmutableStringFieldLiteGenerator::GetBoxedType() const { + return "java.lang.String"; +} + +// =================================================================== + +ImmutableStringOneofFieldLiteGenerator::ImmutableStringOneofFieldLiteGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, Context* context) + : ImmutableStringFieldLiteGenerator(descriptor, messageBitIndex, context) { + const OneofGeneratorInfo* info = + context->GetOneofGeneratorInfo(descriptor->containing_oneof()); + SetCommonOneofVariables(descriptor, info, &variables_); +} + +ImmutableStringOneofFieldLiteGenerator:: + ~ImmutableStringOneofFieldLiteGenerator() {} + +void ImmutableStringOneofFieldLiteGenerator::GenerateMembers( + io::Printer* printer) const { + PrintExtraFieldInfo(variables_, printer); + GOOGLE_DCHECK(HasHazzer(descriptor_)); + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return $has_oneof_case_message$;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n" + " java.lang.String ref $default_init$;\n" + " if ($has_oneof_case_message$) {\n" + " ref = (java.lang.String) $oneof_name$_;\n" + " }\n" + " return ref;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldStringBytesAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public com.google.protobuf.ByteString\n" + " ${$get$capitalized_name$Bytes$}$() {\n" + " java.lang.String ref $default_init$;\n" + " if ($has_oneof_case_message$) {\n" + " ref = (java.lang.String) $oneof_name$_;\n" + " }\n" + " return com.google.protobuf.ByteString.copyFromUtf8(ref);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldAccessorDocComment(printer, descriptor_, SETTER); + printer->Print(variables_, + "private void ${$set$capitalized_name$$}$(\n" + " java.lang.String value) {\n" + "$null_check$" + " $set_oneof_case_message$;\n" + " $oneof_name$_ = value;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER); + printer->Print(variables_, + "private void ${$clear$capitalized_name$$}$() {\n" + " if ($has_oneof_case_message$) {\n" + " $clear_oneof_case_message$;\n" + " $oneof_name$_ = null;\n" + " }\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldStringBytesAccessorDocComment(printer, descriptor_, SETTER); + printer->Print(variables_, + "private void ${$set$capitalized_name$Bytes$}$(\n" + " com.google.protobuf.ByteString value) {\n"); + printer->Annotate("{", "}", descriptor_); + if (CheckUtf8(descriptor_)) { + printer->Print(variables_, " checkByteStringIsUtf8(value);\n"); + } + printer->Print(variables_, + " $oneof_name$_ = value.toStringUtf8();\n" + " $set_oneof_case_message$;\n" + "}\n"); +} + +void ImmutableStringOneofFieldLiteGenerator::GenerateFieldInfo( + io::Printer* printer, std::vector<uint16_t>* output) const { + WriteIntToUtf16CharSequence(descriptor_->number(), output); + WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_), + output); + WriteIntToUtf16CharSequence(descriptor_->containing_oneof()->index(), output); +} + +void ImmutableStringOneofFieldLiteGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + GOOGLE_DCHECK(HasHazzer(descriptor_)); + WriteFieldAccessorDocComment(printer, descriptor_, HAZZER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n" + " return instance.has$capitalized_name$();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldAccessorDocComment(printer, descriptor_, GETTER); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public java.lang.String ${$get$capitalized_name$$}$() {\n" + " return instance.get$capitalized_name$();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldStringBytesAccessorDocComment(printer, descriptor_, GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public com.google.protobuf.ByteString\n" + " ${$get$capitalized_name$Bytes$}$() {\n" + " return instance.get$capitalized_name$Bytes();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldAccessorDocComment(printer, descriptor_, SETTER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" + " java.lang.String value) {\n" + " copyOnWrite();\n" + " instance.set$capitalized_name$(value);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ true); + printer->Print( + variables_, + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" + " copyOnWrite();\n" + " instance.clear$capitalized_name$();\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldStringBytesAccessorDocComment(printer, descriptor_, SETTER, + /* builder */ true); + printer->Print( + variables_, + "$deprecation$public Builder ${$set$capitalized_name$Bytes$}$(\n" + " com.google.protobuf.ByteString value) {\n" + " copyOnWrite();\n" + " instance.set$capitalized_name$Bytes(value);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +// =================================================================== + +RepeatedImmutableStringFieldLiteGenerator:: + RepeatedImmutableStringFieldLiteGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + Context* context) + : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) { + SetPrimitiveVariables(descriptor, messageBitIndex, 0, + context->GetFieldGeneratorInfo(descriptor), + name_resolver_, &variables_); +} + +RepeatedImmutableStringFieldLiteGenerator:: + ~RepeatedImmutableStringFieldLiteGenerator() {} + +int RepeatedImmutableStringFieldLiteGenerator::GetNumBitsForMessage() const { + return 0; +} + +void RepeatedImmutableStringFieldLiteGenerator::GenerateInterfaceMembers( + io::Printer* printer) const { + WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER); + printer->Print(variables_, + "$deprecation$java.util.List<java.lang.String>\n" + " get$capitalized_name$List();\n"); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT); + printer->Print(variables_, + "$deprecation$int get$capitalized_name$Count();\n"); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER); + printer->Print( + variables_, + "$deprecation$java.lang.String get$capitalized_name$(int index);\n"); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER); + printer->Print(variables_, + "$deprecation$com.google.protobuf.ByteString\n" + " get$capitalized_name$Bytes(int index);\n"); +} + +void RepeatedImmutableStringFieldLiteGenerator::GenerateMembers( + io::Printer* printer) const { + printer->Print( + variables_, + "private com.google.protobuf.Internal.ProtobufList<java.lang.String> " + "$name$_;\n"); + PrintExtraFieldInfo(variables_, printer); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public java.util.List<java.lang.String> " + "${$get$capitalized_name$List$}$() {\n" + " return $name$_;\n" // note: unmodifiable list + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" + " return $name$_.size();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public java.lang.String " + "${$get$capitalized_name$$}$(int index) {\n" + " return $name$_.get(index);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldStringBytesAccessorDocComment(printer, descriptor_, + LIST_INDEXED_GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public com.google.protobuf.ByteString\n" + " ${$get$capitalized_name$Bytes$}$(int index) {\n" + " return com.google.protobuf.ByteString.copyFromUtf8(\n" + " $name$_.get(index));\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + printer->Print( + variables_, + "private void ensure$capitalized_name$IsMutable() {\n" + // Use a temporary to avoid a redundant iget-object. + " com.google.protobuf.Internal.ProtobufList<java.lang.String> tmp =\n" + " $name$_;" + " if (!tmp.isModifiable()) {\n" + " $name$_ =\n" + " com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);\n" + " }\n" + "}\n"); + + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER); + printer->Print(variables_, + "private void set$capitalized_name$(\n" + " int index, java.lang.String value) {\n" + "$null_check$" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.set(index, value);\n" + "}\n"); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER); + printer->Print(variables_, + "private void add$capitalized_name$(\n" + " java.lang.String value) {\n" + "$null_check$" + " ensure$capitalized_name$IsMutable();\n" + " $name$_.add(value);\n" + "}\n"); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER); + printer->Print(variables_, + "private void addAll$capitalized_name$(\n" + " java.lang.Iterable<java.lang.String> values) {\n" + " ensure$capitalized_name$IsMutable();\n" + " com.google.protobuf.AbstractMessageLite.addAll(\n" + " values, $name$_);\n" + "}\n"); + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER); + printer->Print(variables_, + "private void clear$capitalized_name$() {\n" + " $name$_ = $empty_list$;\n" + "}\n"); + + WriteFieldStringBytesAccessorDocComment(printer, descriptor_, LIST_ADDER); + printer->Print(variables_, + "private void add$capitalized_name$Bytes(\n" + " com.google.protobuf.ByteString value) {\n"); + if (CheckUtf8(descriptor_)) { + printer->Print(variables_, " checkByteStringIsUtf8(value);\n"); + } + printer->Print(variables_, + " ensure$capitalized_name$IsMutable();\n" + " $name$_.add(value.toStringUtf8());\n" + "}\n"); +} + +void RepeatedImmutableStringFieldLiteGenerator::GenerateBuilderMembers( + io::Printer* printer) const { + WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public java.util.List<java.lang.String>\n" + " ${$get$capitalized_name$List$}$() {\n" + " return java.util.Collections.unmodifiableList(\n" + " instance.get$capitalized_name$List());\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT); + printer->Print( + variables_, + "@java.lang.Override\n" + "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n" + " return instance.get$capitalized_name$Count();\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public java.lang.String " + "${$get$capitalized_name$$}$(int index) {\n" + " return instance.get$capitalized_name$(index);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldStringBytesAccessorDocComment(printer, descriptor_, + LIST_INDEXED_GETTER); + printer->Print(variables_, + "@java.lang.Override\n" + "$deprecation$public com.google.protobuf.ByteString\n" + " ${$get$capitalized_name$Bytes$}$(int index) {\n" + " return instance.get$capitalized_name$Bytes(index);\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder ${$set$capitalized_name$$}$(\n" + " int index, java.lang.String value) {\n" + " copyOnWrite();\n" + " instance.set$capitalized_name$(index, value);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder ${$add$capitalized_name$$}$(\n" + " java.lang.String value) {\n" + " copyOnWrite();\n" + " instance.add$capitalized_name$(value);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, + /* builder */ true); + printer->Print(variables_, + "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n" + " java.lang.Iterable<java.lang.String> values) {\n" + " copyOnWrite();\n" + " instance.addAll$capitalized_name$(values);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ true); + printer->Print( + variables_, + "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n" + " copyOnWrite();\n" + " instance.clear$capitalized_name$();\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); + + WriteFieldStringBytesAccessorDocComment(printer, descriptor_, LIST_ADDER, + /* builder */ true); + printer->Print( + variables_, + "$deprecation$public Builder ${$add$capitalized_name$Bytes$}$(\n" + " com.google.protobuf.ByteString value) {\n" + " copyOnWrite();\n" + " instance.add$capitalized_name$Bytes(value);\n" + " return this;\n" + "}\n"); + printer->Annotate("{", "}", descriptor_); +} + +void RepeatedImmutableStringFieldLiteGenerator::GenerateKotlinDslMembers( + io::Printer* printer) const { + printer->Print( + variables_, + "/**\n" + " * An uninstantiable, behaviorless type to represent the field in\n" + " * generics.\n" + " */\n" + "@kotlin.OptIn" + "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n" + "public class ${$$kt_capitalized_name$Proxy$}$ private constructor()" + " : com.google.protobuf.kotlin.DslProxy()\n"); + + // property for List<String> + WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER); + printer->Print( + variables_, + "$kt_deprecation$public val $kt_name$: " + "com.google.protobuf.kotlin.DslList" + "<kotlin.String, ${$$kt_capitalized_name$Proxy$}$>\n" + " @kotlin.OptIn" + "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n" + " get() = com.google.protobuf.kotlin.DslList(\n" + " $kt_dsl_builder$.${$get$capitalized_name$List$}$()\n" + " )\n"); + + // List<String>.add(String) + WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, + /* builder */ false); + printer->Print(variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"add$kt_capitalized_name$\")\n" + "public fun com.google.protobuf.kotlin.DslList" + "<kotlin.String, ${$$kt_capitalized_name$Proxy$}$>." + "add(value: kotlin.String) {\n" + " $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n" + "}\n"); + + // List<String> += String + WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER, + /* builder */ false); + printer->Print(variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"plusAssign$kt_capitalized_name$\")\n" + "@Suppress(\"NOTHING_TO_INLINE\")\n" + "public inline operator fun com.google.protobuf.kotlin.DslList" + "<kotlin.String, ${$$kt_capitalized_name$Proxy$}$>." + "plusAssign(value: kotlin.String) {\n" + " add(value)\n" + "}\n"); + + // List<String>.addAll(Iterable<String>) + WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, + /* builder */ false); + printer->Print( + variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"addAll$kt_capitalized_name$\")\n" + "public fun com.google.protobuf.kotlin.DslList" + "<kotlin.String, ${$$kt_capitalized_name$Proxy$}$>." + "addAll(values: kotlin.collections.Iterable<kotlin.String>) {\n" + " $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n" + "}\n"); + + // List<String> += Iterable<String> + WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER, + /* builder */ false); + printer->Print( + variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"plusAssignAll$kt_capitalized_name$\")\n" + "@Suppress(\"NOTHING_TO_INLINE\")\n" + "public inline operator fun com.google.protobuf.kotlin.DslList" + "<kotlin.String, ${$$kt_capitalized_name$Proxy$}$>." + "plusAssign(values: kotlin.collections.Iterable<kotlin.String>) {\n" + " addAll(values)\n" + "}\n"); + + // List<String>[Int] = String + WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER, + /* builder */ false); + printer->Print( + variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"set$kt_capitalized_name$\")\n" + "public operator fun com.google.protobuf.kotlin.DslList" + "<kotlin.String, ${$$kt_capitalized_name$Proxy$}$>." + "set(index: kotlin.Int, value: kotlin.String) {\n" + " $kt_dsl_builder$.${$set$capitalized_name$$}$(index, value)\n" + "}"); + + WriteFieldAccessorDocComment(printer, descriptor_, CLEARER, + /* builder */ false); + printer->Print(variables_, + "@kotlin.jvm.JvmSynthetic\n" + "@kotlin.jvm.JvmName(\"clear$kt_capitalized_name$\")\n" + "public fun com.google.protobuf.kotlin.DslList" + "<kotlin.String, ${$$kt_capitalized_name$Proxy$}$>." + "clear() {\n" + " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n" + "}"); +} + +void RepeatedImmutableStringFieldLiteGenerator::GenerateFieldInfo( + io::Printer* printer, std::vector<uint16_t>* output) const { + WriteIntToUtf16CharSequence(descriptor_->number(), output); + WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_), + output); + printer->Print(variables_, "\"$name$_\",\n"); +} + +void RepeatedImmutableStringFieldLiteGenerator::GenerateInitializationCode( + io::Printer* printer) const { + printer->Print(variables_, "$name$_ = $empty_list$;\n"); +} + +std::string RepeatedImmutableStringFieldLiteGenerator::GetBoxedType() const { + return "java.lang.String"; +} + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/java/java_string_field_lite.h b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_string_field_lite.h new file mode 100644 index 00000000..880d41cc --- /dev/null +++ b/NorthstarDedicatedTest/include/protobuf/compiler/java/java_string_field_lite.h @@ -0,0 +1,139 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// 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) +// Author: jonp@google.com (Jon Perlow) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. + +#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_STRING_FIELD_LITE_H__ +#define GOOGLE_PROTOBUF_COMPILER_JAVA_STRING_FIELD_LITE_H__ + +#include <cstdint> +#include <map> +#include <string> + +#include <compiler/java/java_field.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { +class Context; // context.h +class ClassNameResolver; // name_resolver.h +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +namespace google { +namespace protobuf { +namespace compiler { +namespace java { + +class ImmutableStringFieldLiteGenerator : public ImmutableFieldLiteGenerator { + public: + explicit ImmutableStringFieldLiteGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, + Context* context); + ~ImmutableStringFieldLiteGenerator() override; + + // implements ImmutableFieldLiteGenerator + // ------------------------------------ + int GetNumBitsForMessage() const override; + void GenerateInterfaceMembers(io::Printer* printer) const override; + void GenerateMembers(io::Printer* printer) const override; + void GenerateBuilderMembers(io::Printer* printer) const override; + void GenerateInitializationCode(io::Printer* printer) const override; + void GenerateFieldInfo(io::Printer* printer, + std::vector<uint16_t>* output) const override; + void GenerateKotlinDslMembers(io::Printer* printer) const override; + + std::string GetBoxedType() const override; + + protected: + const FieldDescriptor* descriptor_; + std::map<std::string, std::string> variables_; + const int messageBitIndex_; + ClassNameResolver* name_resolver_; + + private: + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableStringFieldLiteGenerator); +}; + +class ImmutableStringOneofFieldLiteGenerator + : public ImmutableStringFieldLiteGenerator { + public: + ImmutableStringOneofFieldLiteGenerator(const FieldDescriptor* descriptor, + int messageBitIndex, Context* context); + ~ImmutableStringOneofFieldLiteGenerator() override; + + private: + void GenerateMembers(io::Printer* printer) const override; + void GenerateBuilderMembers(io::Printer* printer) const override; + void GenerateFieldInfo(io::Printer* printer, + std::vector<uint16_t>* output) const override; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableStringOneofFieldLiteGenerator); +}; + +class RepeatedImmutableStringFieldLiteGenerator + : public ImmutableFieldLiteGenerator { + public: + explicit RepeatedImmutableStringFieldLiteGenerator( + const FieldDescriptor* descriptor, int messageBitIndex, Context* context); + ~RepeatedImmutableStringFieldLiteGenerator() override; + + // implements ImmutableFieldLiteGenerator ------------------------------------ + int GetNumBitsForMessage() const override; + void GenerateInterfaceMembers(io::Printer* printer) const override; + void GenerateMembers(io::Printer* printer) const override; + void GenerateBuilderMembers(io::Printer* printer) const override; + void GenerateInitializationCode(io::Printer* printer) const override; + void GenerateFieldInfo(io::Printer* printer, + std::vector<uint16_t>* output) const override; + void GenerateKotlinDslMembers(io::Printer* printer) const override; + + std::string GetBoxedType() const override; + + private: + const FieldDescriptor* descriptor_; + std::map<std::string, std::string> variables_; + ClassNameResolver* name_resolver_; + + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableStringFieldLiteGenerator); +}; + +} // namespace java +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_STRING_FIELD_LITE_H__ |