I have the following protoc3 message:
message LocalizedString {
map<string, string> translations = 1
}
When compiled into C#, I get the following autogenerated code:
using pb = global::Google.Protobuf;
using pbc = global::Google.Protobuf.Collections;
using pbr = global::Google.Protobuf.Reflection;
using scg = global::System.Collections.Generic;
namespace PKIo {
/// <summary>Holder for reflection information generated from io/common/localization.proto</summary>
public static partial class LocalizationReflection {
#region Descriptor
/// <summary>File descriptor for io/common/localization.proto</summary>
public static pbr::FileDescriptor Descriptor {
get { return descriptor; }
}
private static pbr::FileDescriptor descriptor;
static LocalizationReflection() {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"Chxpby9jb21tb24vbG9jYWxpemF0aW9uLnByb3RvEgJpbyKDAQoPTG9jYWxp",
"emVkU3RyaW5nEjsKDHRyYW5zbGF0aW9ucxgBIAMoCzIlLmlvLkxvY2FsaXpl",
"ZFN0cmluZy5UcmFuc2xhdGlvbnNFbnRyeRozChFUcmFuc2xhdGlvbnNFbnRy",
"eRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAk6AjgBQi1aJHN0YXNoLnBh",
"c3NraXQuY29tL2lvL21vZGVsL3Nkay9nby9pb6oCBFBLSW9iBnByb3RvMw=="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
new pbr::GeneratedClrTypeInfo(typeof(global::PKIo.LocalizedString), global::PKIo.LocalizedString.Parser, new[]{ "Translations" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, })
}));
}
#endregion
}
#region Messages
/// <summary>
/// Localized strings are optionally used to provide translated values for each of supported language.
/// </summary>
public sealed partial class LocalizedString : pb::IMessage<LocalizedString> {
private static readonly pb::MessageParser<LocalizedString> _parser = new pb::MessageParser<LocalizedString>(() => new LocalizedString());
private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<LocalizedString> Parser { get { return _parser; } }
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::PKIo.LocalizationReflection.Descriptor.MessageTypes[0]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public LocalizedString() {
OnConstruction();
}
partial void OnConstruction();
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public LocalizedString(LocalizedString other) : this() {
translations_ = other.translations_.Clone();
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public LocalizedString Clone() {
return new LocalizedString(this);
}
/// <summary>Field number for the "translations" field.</summary>
public const int TranslationsFieldNumber = 1;
private static readonly pbc::MapField<string, string>.Codec _map_translations_codec
= new pbc::MapField<string, string>.Codec(pb::FieldCodec.ForString(10), pb::FieldCodec.ForString(18), 10);
private readonly pbc::MapField<string, string> translations_ = new pbc::MapField<string, string>();
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<string, string> Translations {
get { return translations_; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as LocalizedString);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(LocalizedString other) {
if (ReferenceEquals(other, null)) {
return false;
}
if (ReferenceEquals(other, this)) {
return true;
}
if (!Translations.Equals(other.Translations)) return false;
return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
hash ^= Translations.GetHashCode();
if (_unknownFields != null) {
hash ^= _unknownFields.GetHashCode();
}
return hash;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
return pb::JsonFormatter.ToDiagnosticString(this);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
translations_.WriteTo(output, _map_translations_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
size += translations_.CalculateSize(_map_translations_codec);
if (_unknownFields != null) {
size += _unknownFields.CalculateSize();
}
return size;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(LocalizedString other) {
if (other == null) {
return;
}
translations_.Add(other.translations_);
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
translations_.AddEntriesFrom(input, _map_translations_codec);
break;
}
}
}
}
}
#endregion
}
I have another message that has a LocalizedString property that I am using for as an input to an rpc function, but I cannot figure out how to set the properties for Translations
. In the generated code, Translations
is marked as read only.
How does one construct a protobuf message object that contains a map like this in C#?
So after digging through the documentation, I found that Google.Protobuf.Collections.MapField< TKey, TValue >
has getters and setters.
The values can by either passing a key, value pair or a dictionary to the Add method of the map.
var localizedName = new LocalizedString();
localizedName.Translations.Add(new Dictionary<string, string>(){
{"ES","Hola"},
{"FR","Bonjour"},
{"JA","こんにちは"},
{"TH","สวัสดี"},
});
localizedName.Translations.Add("ZH_HANS", "你好");
To retrive a value there is a TryGetValue
method:
var translation = "";
localizedName.Translations.TryGetValue("TH", out translation);
// translation == "สวัสดี"