diff --git a/.msggen.json b/.msggen.json new file mode 100644 index 000000000000..db8ab9dd7e1b --- /dev/null +++ b/.msggen.json @@ -0,0 +1,234 @@ +{ + "grpc-enum-map": { + "CloseType": { + "mutual": 0, + "unilateral": 1, + "unopened": 2 + }, + "GetinfoAddressType": { + "dns": 0, + "ipv4": 1, + "ipv6": 2, + "torv2": 3, + "torv3": 4, + "websocket": 5 + }, + "GetinfoBindingType": { + "ipv4": 1, + "ipv6": 2, + "local socket": 0, + "torv2": 3, + "torv3": 4 + }, + "ListfundsOutputsStatus": { + "confirmed": 1, + "spent": 2, + "unconfirmed": 0 + }, + "ListpeersPeersChannelsHtlcsDirection": { + "in": 0, + "out": 1 + }, + "ListpeersPeersChannelsHtlcsState": { + "RCVD_ADD_ACK_COMMIT": 3, + "RCVD_ADD_REVOCATION": 2, + "RCVD_REMOVE_ACK_REVOCATION": 9, + "RCVD_REMOVE_COMMIT": 6, + "RCVD_REMOVE_HTLC": 5, + "SENT_ADD_ACK_REVOCATION": 4, + "SENT_ADD_COMMIT": 1, + "SENT_ADD_HTLC": 0, + "SENT_REMOVE_ACK_COMMIT": 8, + "SENT_REMOVE_REVOCATION": 7 + }, + "ListpeersPeersChannelsState": { + "AWAITING_UNILATERAL": 6, + "CHANNELD_AWAITING_LOCKIN": 1, + "CHANNELD_NORMAL": 2, + "CHANNELD_SHUTTING_DOWN": 3, + "CLOSINGD_COMPLETE": 5, + "CLOSINGD_SIGEXCHANGE": 4, + "DUALOPEND_AWAITING_LOCKIN": 10, + "DUALOPEND_OPEN_INIT": 9, + "FUNDING_SPEND_SEEN": 7, + "ONCHAIN": 8, + "OPENINGD": 0 + }, + "ListpeersPeersLogType": { + "BROKEN": 1, + "DEBUG": 4, + "INFO": 3, + "IO_IN": 5, + "IO_OUT": 6, + "SKIPPED": 0, + "UNUSUAL": 2 + } + }, + "grpc-field-map": { + "AddGossip.message": 1, + "AutoCleanInvoice.cycle_seconds": 2, + "AutoCleanInvoice.enabled": 3, + "AutoCleanInvoice.expired_by": 1, + "CheckMessage.message": 1, + "CheckMessage.pubkey": 3, + "CheckMessage.verified": 4, + "CheckMessage.zbase": 2, + "Close.destination": 3, + "Close.fee_negotiation_step": 4, + "Close.force_lease_closed": 6, + "Close.id": 1, + "Close.tx": 8, + "Close.txid": 9, + "Close.type": 7, + "Close.unilateraltimeout": 2, + "Close.wrong_funding": 5, + "Getinfo.address[]": 14, + "Getinfo.address[].address": 3, + "Getinfo.address[].port": 2, + "Getinfo.address[].type": 1, + "Getinfo.alias": 2, + "Getinfo.binding[]": 15, + "Getinfo.binding[].address": 2, + "Getinfo.binding[].port": 3, + "Getinfo.binding[].socket": 4, + "Getinfo.binding[].type": 1, + "Getinfo.blockheight": 11, + "Getinfo.color": 3, + "Getinfo.fees_collected_msat": 13, + "Getinfo.id": 1, + "Getinfo.lightning-dir": 9, + "Getinfo.network": 12, + "Getinfo.num_active_channels": 6, + "Getinfo.num_inactive_channels": 7, + "Getinfo.num_peers": 4, + "Getinfo.num_pending_channels": 5, + "Getinfo.our_features": 10, + "Getinfo.our_features.channel": 3, + "Getinfo.our_features.init": 1, + "Getinfo.our_features.invoice": 4, + "Getinfo.our_features.node": 2, + "Getinfo.version": 8, + "Getinfo.warning_bitcoind_sync": 16, + "Getinfo.warning_lightningd_sync": 17, + "ListChannels.channels[]": 4, + "ListChannels.channels[].active": 8, + "ListChannels.channels[].amount_msat": 5, + "ListChannels.channels[].base_fee_millisatoshi": 10, + "ListChannels.channels[].channel_flags": 7, + "ListChannels.channels[].delay": 12, + "ListChannels.channels[].destination": 2, + "ListChannels.channels[].features": 15, + "ListChannels.channels[].fee_per_millionth": 11, + "ListChannels.channels[].htlc_maximum_msat": 14, + "ListChannels.channels[].htlc_minimum_msat": 13, + "ListChannels.channels[].last_update": 9, + "ListChannels.channels[].message_flags": 6, + "ListChannels.channels[].public": 4, + "ListChannels.channels[].short_channel_id": 3, + "ListChannels.channels[].source": 1, + "ListChannels.destination": 3, + "ListChannels.short_channel_id": 1, + "ListChannels.source": 2, + "ListFunds.channels[]": 3, + "ListFunds.channels[].amount_msat": 3, + "ListFunds.channels[].connected": 6, + "ListFunds.channels[].funding_output": 5, + "ListFunds.channels[].funding_txid": 4, + "ListFunds.channels[].our_amount_msat": 2, + "ListFunds.channels[].peer_id": 1, + "ListFunds.channels[].short_channel_id": 8, + "ListFunds.channels[].state": 7, + "ListFunds.outputs[]": 2, + "ListFunds.outputs[].address": 5, + "ListFunds.outputs[].amount_msat": 3, + "ListFunds.outputs[].blockheight": 8, + "ListFunds.outputs[].output": 2, + "ListFunds.outputs[].redeemscript": 6, + "ListFunds.outputs[].scriptpubkey": 4, + "ListFunds.outputs[].status": 7, + "ListFunds.outputs[].txid": 1, + "ListFunds.spent": 1, + "ListPeers.id": 1, + "ListPeers.level": 2, + "ListPeers.peers[]": 3, + "ListPeers.peers[].channels[]": 4, + "ListPeers.peers[].channels[].channel_id": 6, + "ListPeers.peers[].channels[].close_to": 14, + "ListPeers.peers[].channels[].close_to_addr": 47, + "ListPeers.peers[].channels[].closer": 17, + "ListPeers.peers[].channels[].dust_limit_msat": 26, + "ListPeers.peers[].channels[].features[]": 18, + "ListPeers.peers[].channels[].fee_base_msat": 24, + "ListPeers.peers[].channels[].fee_proportional_millionths": 25, + "ListPeers.peers[].channels[].feerate": 3, + "ListPeers.peers[].channels[].feerate.perkb": 2, + "ListPeers.peers[].channels[].feerate.perkw": 1, + "ListPeers.peers[].channels[].funding": 19, + "ListPeers.peers[].channels[].funding.local_msat": 1, + "ListPeers.peers[].channels[].funding.pushed_msat": 3, + "ListPeers.peers[].channels[].funding.remote_msat": 2, + "ListPeers.peers[].channels[].funding_outnum": 8, + "ListPeers.peers[].channels[].funding_txid": 7, + "ListPeers.peers[].channels[].htlcs[]": 46, + "ListPeers.peers[].channels[].htlcs[].amount_msat": 3, + "ListPeers.peers[].channels[].htlcs[].direction": 1, + "ListPeers.peers[].channels[].htlcs[].expiry": 4, + "ListPeers.peers[].channels[].htlcs[].id": 2, + "ListPeers.peers[].channels[].htlcs[].local_trimmed": 6, + "ListPeers.peers[].channels[].htlcs[].payment_hash": 5, + "ListPeers.peers[].channels[].htlcs[].state": 8, + "ListPeers.peers[].channels[].htlcs[].status": 7, + "ListPeers.peers[].channels[].in_fulfilled_msat": 41, + "ListPeers.peers[].channels[].in_offered_msat": 39, + "ListPeers.peers[].channels[].in_payments_fulfilled": 40, + "ListPeers.peers[].channels[].in_payments_offered": 38, + "ListPeers.peers[].channels[].inflight[]": 13, + "ListPeers.peers[].channels[].inflight[].feerate": 3, + "ListPeers.peers[].channels[].inflight[].funding_outnum": 2, + "ListPeers.peers[].channels[].inflight[].funding_txid": 1, + "ListPeers.peers[].channels[].inflight[].our_funding_msat": 5, + "ListPeers.peers[].channels[].inflight[].scratch_txid": 6, + "ListPeers.peers[].channels[].inflight[].total_funding_msat": 4, + "ListPeers.peers[].channels[].initial_feerate": 9, + "ListPeers.peers[].channels[].last_feerate": 10, + "ListPeers.peers[].channels[].max_accepted_htlcs": 35, + "ListPeers.peers[].channels[].max_to_us_msat": 22, + "ListPeers.peers[].channels[].max_total_htlc_in_msat": 27, + "ListPeers.peers[].channels[].min_to_us_msat": 21, + "ListPeers.peers[].channels[].minimum_htlc_in_msat": 32, + "ListPeers.peers[].channels[].next_fee_step": 12, + "ListPeers.peers[].channels[].next_feerate": 11, + "ListPeers.peers[].channels[].opener": 16, + "ListPeers.peers[].channels[].our_reserve_msat": 29, + "ListPeers.peers[].channels[].our_to_self_delay": 34, + "ListPeers.peers[].channels[].out_fulfilled_msat": 45, + "ListPeers.peers[].channels[].out_offered_msat": 43, + "ListPeers.peers[].channels[].out_payments_fulfilled": 44, + "ListPeers.peers[].channels[].out_payments_offered": 42, + "ListPeers.peers[].channels[].owner": 4, + "ListPeers.peers[].channels[].private": 15, + "ListPeers.peers[].channels[].receivable_msat": 31, + "ListPeers.peers[].channels[].scratch_txid": 2, + "ListPeers.peers[].channels[].short_channel_id": 5, + "ListPeers.peers[].channels[].spendable_msat": 30, + "ListPeers.peers[].channels[].state": 1, + "ListPeers.peers[].channels[].state_changes[]": 36, + "ListPeers.peers[].channels[].status[]": 37, + "ListPeers.peers[].channels[].their_reserve_msat": 28, + "ListPeers.peers[].channels[].their_to_self_delay": 33, + "ListPeers.peers[].channels[].to_us_msat": 20, + "ListPeers.peers[].channels[].total_msat": 23, + "ListPeers.peers[].connected": 2, + "ListPeers.peers[].features": 6, + "ListPeers.peers[].id": 1, + "ListPeers.peers[].log[]": 3, + "ListPeers.peers[].log[].data": 7, + "ListPeers.peers[].log[].log": 5, + "ListPeers.peers[].log[].node_id": 6, + "ListPeers.peers[].log[].num_skipped": 2, + "ListPeers.peers[].log[].source": 4, + "ListPeers.peers[].log[].time": 3, + "ListPeers.peers[].log[].type": 1, + "ListPeers.peers[].netaddr[]": 5 + } +} \ No newline at end of file diff --git a/cln-grpc/proto/node.proto b/cln-grpc/proto/node.proto index 76610e9f6209..b834c9c34329 100644 --- a/cln-grpc/proto/node.proto +++ b/cln-grpc/proto/node.proto @@ -31,13 +31,20 @@ message GetinfoResponse { uint32 num_inactive_channels = 7; string version = 8; string lightning_dir = 9; - uint32 blockheight = 10; - string network = 11; - Amount fees_collected_msat = 12; - repeated GetinfoAddress address = 13; - repeated GetinfoBinding binding = 14; - optional string warning_bitcoind_sync = 15; - optional string warning_lightningd_sync = 16; + uint32 blockheight = 11; + string network = 12; + Amount fees_collected_msat = 13; + repeated GetinfoAddress address = 14; + repeated GetinfoBinding binding = 15; + optional string warning_bitcoind_sync = 16; + optional string warning_lightningd_sync = 17; +} + +message GetinfoOur_features { + bytes init = 1; + bytes node = 2; + bytes channel = 3; + bytes invoice = 4; } message GetinfoAddress { @@ -76,7 +83,7 @@ message ListpeersRequest { } message ListpeersResponse { - repeated ListpeersPeers peers = 1; + repeated ListpeersPeers peers = 3; } message ListpeersPeers { @@ -129,43 +136,44 @@ message ListpeersPeersChannels { optional string short_channel_id = 5; optional bytes channel_id = 6; optional bytes funding_txid = 7; - optional string initial_feerate = 8; - optional string last_feerate = 9; - optional string next_feerate = 10; - optional uint32 next_fee_step = 11; - repeated ListpeersPeersChannelsInflight inflight = 12; - optional bytes close_to = 13; - optional bool private = 14; - ChannelSide opener = 15; - optional ChannelSide closer = 16; - repeated string features = 17; - optional Amount to_us_msat = 19; - optional Amount min_to_us_msat = 20; - optional Amount max_to_us_msat = 21; - optional Amount total_msat = 22; - optional Amount fee_base_msat = 23; - optional uint32 fee_proportional_millionths = 24; - optional Amount dust_limit_msat = 25; - optional Amount max_total_htlc_in_msat = 26; - optional Amount their_reserve_msat = 27; - optional Amount our_reserve_msat = 28; - optional Amount spendable_msat = 29; - optional Amount receivable_msat = 30; - optional Amount minimum_htlc_in_msat = 31; - optional uint32 their_to_self_delay = 32; - optional uint32 our_to_self_delay = 33; - optional uint32 max_accepted_htlcs = 34; - repeated string status = 36; - optional uint64 in_payments_offered = 37; - optional Amount in_offered_msat = 38; - optional uint64 in_payments_fulfilled = 39; - optional Amount in_fulfilled_msat = 40; - optional uint64 out_payments_offered = 41; - optional Amount out_offered_msat = 42; - optional uint64 out_payments_fulfilled = 43; - optional Amount out_fulfilled_msat = 44; - repeated ListpeersPeersChannelsHtlcs htlcs = 45; - optional string close_to_addr = 46; + optional uint32 funding_outnum = 8; + optional string initial_feerate = 9; + optional string last_feerate = 10; + optional string next_feerate = 11; + optional uint32 next_fee_step = 12; + repeated ListpeersPeersChannelsInflight inflight = 13; + optional bytes close_to = 14; + optional bool private = 15; + ChannelSide opener = 16; + optional ChannelSide closer = 17; + repeated string features = 18; + optional Amount to_us_msat = 20; + optional Amount min_to_us_msat = 21; + optional Amount max_to_us_msat = 22; + optional Amount total_msat = 23; + optional Amount fee_base_msat = 24; + optional uint32 fee_proportional_millionths = 25; + optional Amount dust_limit_msat = 26; + optional Amount max_total_htlc_in_msat = 27; + optional Amount their_reserve_msat = 28; + optional Amount our_reserve_msat = 29; + optional Amount spendable_msat = 30; + optional Amount receivable_msat = 31; + optional Amount minimum_htlc_in_msat = 32; + optional uint32 their_to_self_delay = 33; + optional uint32 our_to_self_delay = 34; + optional uint32 max_accepted_htlcs = 35; + repeated string status = 37; + optional uint64 in_payments_offered = 38; + optional Amount in_offered_msat = 39; + optional uint64 in_payments_fulfilled = 40; + optional Amount in_fulfilled_msat = 41; + optional uint64 out_payments_offered = 42; + optional Amount out_offered_msat = 43; + optional uint64 out_payments_fulfilled = 44; + optional Amount out_fulfilled_msat = 45; + repeated ListpeersPeersChannelsHtlcs htlcs = 46; + optional string close_to_addr = 47; } message ListpeersPeersChannelsFeerate { @@ -185,6 +193,7 @@ message ListpeersPeersChannelsInflight { message ListpeersPeersChannelsFunding { Amount local_msat = 1; Amount remote_msat = 2; + Amount pushed_msat = 3; } message ListpeersPeersChannelsHtlcs { @@ -221,8 +230,8 @@ message ListfundsRequest { } message ListfundsResponse { - repeated ListfundsOutputs outputs = 1; - repeated ListfundsChannels channels = 2; + repeated ListfundsOutputs outputs = 2; + repeated ListfundsChannels channels = 3; } message ListfundsOutputs { @@ -260,24 +269,25 @@ message ListchannelsRequest { } message ListchannelsResponse { - repeated ListchannelsChannels channels = 1; + repeated ListchannelsChannels channels = 4; } message ListchannelsChannels { bytes source = 1; bytes destination = 2; - bool public = 3; - Amount amount_msat = 4; - uint32 message_flags = 5; - uint32 channel_flags = 6; - bool active = 7; - uint32 last_update = 8; - uint32 base_fee_millisatoshi = 9; - uint32 fee_per_millionth = 10; - uint32 delay = 11; - Amount htlc_minimum_msat = 12; - optional Amount htlc_maximum_msat = 13; - bytes features = 14; + string short_channel_id = 3; + bool public = 4; + Amount amount_msat = 5; + uint32 message_flags = 6; + uint32 channel_flags = 7; + bool active = 8; + uint32 last_update = 9; + uint32 base_fee_millisatoshi = 10; + uint32 fee_per_millionth = 11; + uint32 delay = 12; + Amount htlc_minimum_msat = 13; + optional Amount htlc_maximum_msat = 14; + bytes features = 15; } message AddgossipRequest { @@ -293,9 +303,9 @@ message AutocleaninvoiceRequest { } message AutocleaninvoiceResponse { - bool enabled = 1; - optional uint64 expired_by = 2; - optional uint64 cycle_seconds = 3; + bool enabled = 3; + optional uint64 expired_by = 1; + optional uint64 cycle_seconds = 2; } message CheckmessageRequest { @@ -305,8 +315,8 @@ message CheckmessageRequest { } message CheckmessageResponse { - bool verified = 1; - optional bytes pubkey = 2; + bool verified = 4; + optional bytes pubkey = 3; } message CloseRequest { @@ -325,7 +335,7 @@ message CloseResponse { UNILATERAL = 1; UNOPENED = 2; } - CloseType item_type = 1; - optional bytes tx = 2; - optional bytes txid = 3; + CloseType item_type = 7; + optional bytes tx = 8; + optional bytes txid = 9; } diff --git a/cln-grpc/src/convert.rs b/cln-grpc/src/convert.rs index 3efce232d4b3..5dbfd54eef97 100644 --- a/cln-grpc/src/convert.rs +++ b/cln-grpc/src/convert.rs @@ -110,6 +110,7 @@ impl From<&responses::ListpeersPeersChannels> for pb::ListpeersPeersChannels { short_channel_id: c.short_channel_id.clone(), channel_id: c.channel_id.as_ref().map(|v| hex::decode(&v).unwrap()), funding_txid: c.funding_txid.as_ref().map(|v| hex::decode(&v).unwrap()), + funding_outnum: c.funding_outnum.clone(), initial_feerate: c.initial_feerate.clone(), last_feerate: c.last_feerate.clone(), next_feerate: c.next_feerate.clone(), @@ -222,6 +223,7 @@ impl From<&responses::ListchannelsChannels> for pb::ListchannelsChannels { Self { source: hex::decode(&c.source).unwrap(), destination: hex::decode(&c.destination).unwrap(), + short_channel_id: c.short_channel_id.clone(), public: c.public.clone(), amount_msat: Some(c.amount_msat.into()), message_flags: c.message_flags.into(), diff --git a/cln-rpc/src/model.rs b/cln-rpc/src/model.rs index d7c6e699532b..3e6a0fc76f93 100644 --- a/cln-rpc/src/model.rs +++ b/cln-rpc/src/model.rs @@ -123,6 +123,18 @@ pub mod responses { #[allow(unused_imports)] use serde::{{Deserialize, Serialize}}; + #[derive(Clone, Debug, Deserialize, Serialize)] + pub struct GetinfoOur_features { + #[serde(alias = "init")] + pub init: String, + #[serde(alias = "node")] + pub node: String, + #[serde(alias = "channel")] + pub channel: String, + #[serde(alias = "invoice")] + pub invoice: String, + } + /// Type of connection #[derive(Copy, Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "lowercase")] @@ -345,6 +357,8 @@ pub mod responses { pub local_msat: Amount, #[serde(alias = "remote_msat")] pub remote_msat: Amount, + #[serde(alias = "pushed_msat")] + pub pushed_msat: Amount, } #[derive(Clone, Debug, Deserialize, Serialize)] @@ -453,6 +467,8 @@ pub mod responses { pub channel_id: Option, #[serde(alias = "funding_txid", skip_serializing_if = "Option::is_none")] pub funding_txid: Option, + #[serde(alias = "funding_outnum", skip_serializing_if = "Option::is_none")] + pub funding_outnum: Option, #[serde(alias = "initial_feerate", skip_serializing_if = "Option::is_none")] pub initial_feerate: Option, #[serde(alias = "last_feerate", skip_serializing_if = "Option::is_none")] @@ -461,7 +477,7 @@ pub mod responses { pub next_feerate: Option, #[serde(alias = "next_fee_step", skip_serializing_if = "Option::is_none")] pub next_fee_step: Option, - #[serde(alias = "inflight[]")] + #[serde(alias = "inflight")] pub inflight: Vec, #[serde(alias = "close_to", skip_serializing_if = "Option::is_none")] pub close_to: Option, @@ -471,7 +487,7 @@ pub mod responses { #[serde(rename = "opener")] pub opener: ChannelSide, pub closer: Option, - #[serde(alias = "features[]")] + #[serde(alias = "features")] pub features: Vec, #[serde(alias = "to_us_msat", skip_serializing_if = "Option::is_none")] pub to_us_msat: Option, @@ -505,9 +521,9 @@ pub mod responses { pub our_to_self_delay: Option, #[serde(alias = "max_accepted_htlcs", skip_serializing_if = "Option::is_none")] pub max_accepted_htlcs: Option, - #[serde(alias = "state_changes[]")] + #[serde(alias = "state_changes")] pub state_changes: Vec, - #[serde(alias = "status[]")] + #[serde(alias = "status")] pub status: Vec, #[serde(alias = "in_payments_offered", skip_serializing_if = "Option::is_none")] pub in_payments_offered: Option, @@ -525,7 +541,7 @@ pub mod responses { pub out_payments_fulfilled: Option, #[serde(alias = "out_fulfilled_msat", skip_serializing_if = "Option::is_none")] pub out_fulfilled_msat: Option, - #[serde(alias = "htlcs[]")] + #[serde(alias = "htlcs")] pub htlcs: Vec, #[serde(alias = "close_to_addr", skip_serializing_if = "Option::is_none")] pub close_to_addr: Option, @@ -537,11 +553,11 @@ pub mod responses { pub id: String, #[serde(alias = "connected")] pub connected: bool, - #[serde(alias = "log[]")] + #[serde(alias = "log")] pub log: Vec, - #[serde(alias = "channels[]")] + #[serde(alias = "channels")] pub channels: Vec, - #[serde(alias = "netaddr[]")] + #[serde(alias = "netaddr")] pub netaddr: Vec, #[serde(alias = "features", skip_serializing_if = "Option::is_none")] pub features: Option, @@ -549,7 +565,7 @@ pub mod responses { #[derive(Clone, Debug, Deserialize, Serialize)] pub struct ListpeersResponse { - #[serde(alias = "peers[]")] + #[serde(alias = "peers")] pub peers: Vec, } @@ -628,6 +644,8 @@ pub mod responses { pub source: String, #[serde(alias = "destination")] pub destination: String, + #[serde(alias = "short_channel_id")] + pub short_channel_id: String, #[serde(alias = "public")] pub public: bool, #[serde(alias = "amount_msat")] diff --git a/contrib/msggen/msggen/__main__.py b/contrib/msggen/msggen/__main__.py index 6b4069e17727..5700b9764a28 100644 --- a/contrib/msggen/msggen/__main__.py +++ b/contrib/msggen/msggen/__main__.py @@ -126,12 +126,12 @@ def load_jsonrpc_service(): return service -def gengrpc(service): +def gengrpc(service, meta): """Load all mapped RPC methods, wrap them in a Service, and split them into messages. """ fname = repo_root() / "cln-grpc" / "proto" / "node.proto" dest = open(fname, "w") - GrpcGenerator(dest).generate(service) + GrpcGenerator(dest, meta).generate(service) fname = repo_root() / "cln-grpc" / "src" / "convert.rs" dest = open(fname, "w") @@ -149,10 +149,22 @@ def genrustjsonrpc(service): RustGenerator(dest).generate(service) +def load_msggen_meta(): + meta = json.load(open('.msggen.json', 'r')) + return meta + + +def write_msggen_meta(meta): + with open('.msggen.json', 'w') as f: + json.dump(meta, f, sort_keys=True, indent=4) + + def run(): service = load_jsonrpc_service() - gengrpc(service) + meta = load_msggen_meta() + gengrpc(service, meta) genrustjsonrpc(service) + write_msggen_meta(meta) if __name__ == "__main__": diff --git a/contrib/msggen/msggen/grpc.py b/contrib/msggen/msggen/grpc.py index 5f0421b92ceb..73e1fe2aee52 100644 --- a/contrib/msggen/msggen/grpc.py +++ b/contrib/msggen/msggen/grpc.py @@ -1,6 +1,6 @@ # A grpc model from .model import ArrayField, Field, CompositeField, EnumField, PrimitiveField, Service -from typing import TextIO, List +from typing import TextIO, List, Dict, Any from textwrap import indent, dedent import re import logging @@ -44,9 +44,10 @@ class GrpcGenerator: """A generator that generates protobuf files. """ - def __init__(self, dest: TextIO): + def __init__(self, dest: TextIO, meta: Dict[str, Any]): self.dest = dest self.logger = logging.getLogger("msggen.grpc.GrpcGenerator") + self.meta = meta def write(self, text: str, cleanup: bool = True) -> None: if cleanup: @@ -54,6 +55,56 @@ def write(self, text: str, cleanup: bool = True) -> None: else: self.dest.write(text) + def field2number(self, field): + m = self.meta['grpc-field-map'] + # Simple case first: if we've already assigned a number let's reuse that + if field.path in m: + return m[field.path] + + # Now let's find the highest number we have in the parent + # context + parent = '.'.join(field.path.split('.')[:-1]) + maxnum = 0 + for k, v in m.items(): + parent2 = '.'.join(k.split('.')[:-1]) + if parent2 == parent: + maxnum = max(maxnum, v) + + self.meta['grpc-field-map'][field.path] = maxnum + 1 + self.logger.warn(f"Assigning new field number to {field.path} => {m[field.path]}") + + return self.meta['grpc-field-map'][field.path] + + def enumerate_fields(self, fields): + """Use the meta map to identify which number this field will get. + """ + for f in fields: + yield (self.field2number(f), f) + + def enumvar2number(self, typename, variant): + """Find an existing variant number of generate a new one. + + If we don't have a variant number yet we'll just take the + largest one assigned so far and increment it by 1. """ + m = self.meta['grpc-enum-map'] + variant = str(variant) + if typename not in m: + m[typename] = {} + + variants = m[typename] + if variant in variants: + return variants[variant] + + # Now find the maximum and increment once + n = max(variants.values()) if len(variants) else -1 + + m[typename][variant] = n + 1 + return m[typename][variant] + + def enumerate_enum(self, typename, variants): + for v in variants: + yield (self.enumvar2number(typename, v), v) + def gather_types(self, service): """Gather all types that might need to be defined. """ @@ -100,7 +151,7 @@ def generate_enum(self, e: EnumField, indent=0): self.write(f"{prefix}// {e.path}\n", False) self.write(f"{prefix}enum {e.typename} {{\n", False) - for i, v in enumerate(e.variants): + for i, v in self.enumerate_enum(e.typename, e.variants): self.logger.debug(f"Generating enum variant {v}") self.write(f"{prefix}\t{v.normalized()} = {i};\n", False) @@ -115,11 +166,11 @@ def generate_message(self, message: CompositeField): """) # Declare enums inline so they are scoped correctly in C++ - for i, f in enumerate(message.fields): + for _, f in enumerate(message.fields): if isinstance(f, EnumField) and f.path not in overrides.keys(): self.generate_enum(f, indent=1) - for i, f in enumerate(message.fields): + for i, f in self.enumerate_fields(message.fields): if overrides.get(f.path, "") is None: continue @@ -128,17 +179,17 @@ def generate_message(self, message: CompositeField): typename = typemap.get(f.itemtype.typename, f.itemtype.typename) if f.path in overrides: typename = overrides[f.path] - self.write(f"\trepeated {typename} {f.normalized()} = {i+1};\n", False) + self.write(f"\trepeated {typename} {f.normalized()} = {i};\n", False) elif isinstance(f, PrimitiveField): typename = typemap.get(f.typename, f.typename) if f.path in overrides: typename = overrides[f.path] - self.write(f"\t{opt}{typename} {f.normalized()} = {i+1};\n", False) + self.write(f"\t{opt}{typename} {f.normalized()} = {i};\n", False) elif isinstance(f, EnumField): typename = f.typename if f.path in overrides: typename = overrides[f.path] - self.write(f"\t{opt}{typename} {f.normalized()} = {i+1};\n", False) + self.write(f"\t{opt}{typename} {f.normalized()} = {i};\n", False) self.write(f"""}} """)