Lista de dicionários Protobuf

Aug 18 2020

Estou tentando definir uma lista de dicionários no meu .proto

Todos os exemplos que encontrei fornecem um dicionário com uma única chave, par de valores:

message Pair {
   string key = 1;
   string value = 2;
}

message Dictionary {
   repeated Pair pairs = 1;
}

ou algo como:

message Dictionary {
    message Pair {
        map<string, string> values = 1;
    }
    repeated Pair pairs = 1;
}

mas como eu lidaria com um dicionário maior de tipos mistos?

{
'k1': 1,
'k2': 2,
'k3': 'three',
'k4': [1,2,3]
}

Para complicar ainda mais as coisas, depois de definir o dicionário de valores mistos, preciso criar uma mensagem que é uma lista desses dicionários. Presumo que seja tão fácil quanto criar uma outra mensagem repetida com o dicionário aninhado:

message DictList {
    repeated Dictionary dlist = 1;
}

Respostas

1 dmaixner Aug 18 2020 at 17:22

Algumas ideias que tive:

  1. Parece que deveria ser possível (se você conhece todos os tipos de valor antecipadamente) para usar oneofpara o valor (https://developers.google.com/protocol-buffers/docs/proto3#oneof) Isso poderia resolver o problema, por exemplo
message Value {
    oneof oneof_values {
        string svalue = 1;
        int ivalue = 2;
        ...
    }
}

message Pair {
   string key = 1;
   Value value = 2;
}

message Dictionary {
   repeated Pair pairs = 1;
}

Você não pode usar mapou repeateddentro dele oneof.

  1. Você pode usar campos opcionais e defini-los todos como valores na definição da mensagem. Em seguida, defina apenas aqueles que você realmente usa.

  2. Você pode usar wrappers ou tipos conhecidos, por exemplo Value:https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.Value

EDITAR

para o Value, pode ser usado assim:

map<string, google.protobuf.Value> dict = 1;
  1. Use struct(conforme sugerido por for_stack), pode ser visto aqui: Como você cria um Protobuf Struct a partir de um Python Dict?